Skip to content

Commit 234e919

Browse files
committed
php sort
1 parent dcd4745 commit 234e919

21 files changed

+782
-1090
lines changed

1.bubbleSort.md renamed to 01.bubbleSort.md

Lines changed: 14 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -31,49 +31,21 @@
3131
当输入的数据是反序时(写一个 for 循环反序输出数据不就行了,干嘛要用你冒泡排序呢,我是闲的吗)。
3232

3333

34-
## 5. JavaScript 代码实现
35-
36-
```js
37-
function bubbleSort(arr) {
38-
var len = arr.length;
39-
for (var i = 0; i < len - 1; i++) {
40-
for (var j = 0; j < len - 1 - i; j++) {
41-
if (arr[j] > arr[j+1]) { // 相邻元素两两对比
42-
var temp = arr[j+1]; // 元素交换
43-
arr[j+1] = arr[j];
44-
arr[j] = temp;
34+
## 5. PHP 代码实现
35+
36+
```php
37+
function bubbleSort($arr)
38+
{
39+
$len = count($arr);
40+
for ($i = 0; $i < $len - 1; $i++) {
41+
for ($j = 0; $j < $len - 1 - $i; $j++) {
42+
if ($arr[$j] > $arr[$j+1]) {
43+
$tmp = $arr[$j];
44+
$arr[$j] = $arr[$j+1];
45+
$arr[$j+1] = $tmp;
4546
}
4647
}
4748
}
48-
return arr;
49+
return $arr;
4950
}
50-
```
51-
52-
53-
54-
## 6. Python 代码实现
55-
56-
```python
57-
def bubbleSort(arr):
58-
for i in range(1, len(arr)):
59-
for j in range(0, len(arr)-i):
60-
if arr[j] > arr[j+1]:
61-
arr[j], arr[j + 1] = arr[j + 1], arr[j]
62-
return arr
63-
```
64-
65-
## 7. Go 代码实现
66-
67-
```go
68-
func bubbleSort(arr []int) []int {
69-
length := len(arr)
70-
for i := 0; i < length; i++ {
71-
for j := 0; j < length-1-i; j++ {
72-
if arr[j] > arr[j+1] {
73-
arr[j], arr[j+1] = arr[j+1], arr[j]
74-
}
75-
}
76-
}
77-
return arr
78-
}
79-
```
51+
```

02.selectionSort.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# 选择排序
2+
3+
选择排序是一种简单直观的排序算法,无论什么数据进去都是 O(n²) 的时间复杂度。所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。
4+
5+
6+
## 1. 算法步骤
7+
8+
1. 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置
9+
10+
2. 再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
11+
12+
3. 重复第二步,直到所有元素均排序完毕。
13+
14+
15+
## 2. 动图演示
16+
17+
![动图演示](res/selectionSort.gif)
18+
19+
20+
## 3. PHP 代码实现
21+
22+
```php
23+
function selectionSort($arr)
24+
{
25+
$len = count($arr);
26+
for ($i = 0; $i < $len - 1; $i++) {
27+
$minIndex = $i;
28+
for ($j = $i + 1; $j < $len; $j++) {
29+
if ($arr[$j] < $arr[$minIndex]) {
30+
$minIndex = $j;
31+
}
32+
}
33+
$temp = $arr[$i];
34+
$arr[$i] = $arr[$minIndex];
35+
$arr[$minIndex] = $temp;
36+
}
37+
return $arr;
38+
}
39+
```

03.insertionSort.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# 插入排序
2+
3+
插入排序的代码实现虽然没有冒泡排序和选择排序那么简单粗暴,但它的原理应该是最容易理解的了,因为只要打过扑克牌的人都应该能够秒懂。插入排序是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
4+
5+
插入排序和冒泡排序一样,也有一种优化算法,叫做拆半插入。
6+
7+
8+
## 1. 算法步骤
9+
10+
1. 将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。
11+
12+
2. 从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)
13+
14+
15+
## 2. 动图演示
16+
17+
![动图演示](res/insertionSort.gif)
18+
19+
20+
## 3. PHP 代码实现
21+
22+
```php
23+
function insertionSort($arr) {
24+
$len = count($arr);
25+
for ($i = 1; $i < $len; $i++) {
26+
$preIndex = $i - 1;
27+
$current = $arr[$i];
28+
while($preIndex >= 0 && $arr[$preIndex] > $current) {
29+
$arr[$preIndex+1] = $arr[$preIndex];
30+
$preIndex--;
31+
}
32+
$arr[$preIndex+1] = $current;
33+
}
34+
return $arr;
35+
}
36+
```
37+

04.shellSort.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# 希尔排序
2+
3+
希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。但希尔排序是非稳定排序算法。
4+
5+
希尔排序是基于插入排序的以下两点性质而提出改进方法的:
6+
7+
- 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率;
8+
- 但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位;
9+
10+
希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。
11+
12+
13+
## 1. 算法步骤
14+
15+
1. 选择一个增量序列 t1,t2,……,tk,其中 ti > tj, tk = 1;
16+
17+
2. 按增量序列个数 k,对序列进行 k 趟排序;
18+
19+
3. 每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。
20+
21+
22+
## 2. PHP 代码实现
23+
24+
```php
25+
function shellSort($arr) {
26+
$len = count($arr);
27+
$temp = 0;
28+
$gap = 1;
29+
while($gap < $len / 3) {
30+
$gap = $gap * 3 + 1;
31+
}
32+
for ($gap; $gap > 0; $gap = floor($gap / 3)) {
33+
for ($i = $gap; $i < $len; $i++) {
34+
$temp = $arr[$i];
35+
for ($j = $i - $gap; $j >= 0 && $arr[$j] > $temp; $j -= $gap) {
36+
$arr[$j+$gap] = $arr[$j];
37+
}
38+
$arr[$j+$gap] = $temp;
39+
}
40+
}
41+
return $arr;
42+
}
43+
```

05.mergeSort.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# 归并排序
2+
3+
归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
4+
5+
作为一种典型的分而治之思想的算法应用,归并排序的实现由两种方法:
6+
- 自上而下的递归(所有递归的方法都可以用迭代重写,所以就有了第 2 种方法);
7+
- 自下而上的迭代;
8+
9+
在《数据结构与算法 JavaScript 描述》中,作者给出了自下而上的迭代方法。但是对于递归法,作者却认为:
10+
11+
> However, it is not possible to do so in JavaScript, as the recursion goes too deep for the language to handle.
12+
>
13+
> 然而,在 JavaScript 中这种方式不太可行,因为这个算法的递归深度对它来讲太深了。
14+
15+
16+
说实话,我不太理解这句话。意思是 JavaScript 编译器内存太小,递归太深容易造成内存溢出吗?还望有大神能够指教。
17+
18+
和选择排序一样,归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是 O(nlogn) 的时间复杂度。代价是需要额外的内存空间。
19+
20+
21+
## 2. 算法步骤
22+
23+
1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;
24+
25+
2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置;
26+
27+
3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;
28+
29+
4. 重复步骤 3 直到某一指针达到序列尾;
30+
31+
5. 将另一序列剩下的所有元素直接复制到合并序列尾。
32+
33+
34+
## 3. 动图演示
35+
36+
![动图演示](res/mergeSort.gif)
37+
38+
39+
## 4. PHP 代码实现
40+
41+
```php
42+
function mergeSort($arr) {
43+
$len = count($arr);
44+
if ($len < 2) {
45+
return $arr;
46+
}
47+
$middle = floor($len / 2);
48+
$left = array_slice($arr, 0, $middle);
49+
$right = array_slice($arr, $middle);
50+
return merge(mergeSort($left), mergeSort($right));
51+
}
52+
53+
function merge($left, $right)
54+
{
55+
$result = [];
56+
57+
while (count($left) > 0 && count($right) > 0) {
58+
if ($left[0] <= $right[0]) {
59+
$result[] = array_shift($left);
60+
} else {
61+
$result[] = array_shift($right);
62+
}
63+
}
64+
65+
while (count($left))
66+
$result[] = array_shift($left);
67+
68+
while (count($right))
69+
$result[] = array_shift($right);
70+
71+
return $result;
72+
}
73+
74+
```

06.quickSort.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# 快速排序
2+
3+
快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要 Ο(nlogn) 次比较。在最坏状况下则需要 Ο(n2) 次比较,但这种状况并不常见。事实上,快速排序通常明显比其他 Ο(nlogn) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。
4+
5+
快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。
6+
7+
快速排序又是一种分而治之思想在排序算法上的典型应用。本质上来看,快速排序应该算是在冒泡排序基础上的递归分治法。
8+
9+
快速排序的名字起的是简单粗暴,因为一听到这个名字你就知道它存在的意义,就是快,而且效率高!它是处理大数据最快的排序算法之一了。虽然 Worst Case 的时间复杂度达到了 O(n²),但是人家就是优秀,在大多数情况下都比平均时间复杂度为 O(n logn) 的排序算法表现要更好,可是这是为什么呢,我也不知道。好在我的强迫症又犯了,查了 N 多资料终于在《算法艺术与信息学竞赛》上找到了满意的答案:
10+
11+
> 快速排序的最坏运行情况是 O(n²),比如说顺序数列的快排。但它的平摊期望时间是 O(nlogn),且 O(nlogn) 记号中隐含的常数因子很小,比复杂度稳定等于 O(nlogn) 的归并排序要小很多。所以,对绝大多数顺序性较弱的随机数列而言,快速排序总是优于归并排序。
12+
13+
14+
## 1. 算法步骤
15+
16+
1. 从数列中挑出一个元素,称为 “基准”(pivot);
17+
18+
2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
19+
20+
3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;
21+
22+
递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。
23+
24+
25+
## 2. 动图演示
26+
27+
![动图演示](res/quickSort.gif)
28+
29+
30+
## 3. PHP 代码实现
31+
32+
```php
33+
function quickSort($arr)
34+
{
35+
if (count($arr) <= 1)
36+
return $arr;
37+
$middle = $arr[0];
38+
$leftArray = array();
39+
$rightArray = array();
40+
41+
for ($i = 1; $i < count($arr); $i++) {
42+
if ($arr[$i] > $middle)
43+
$rightArray[] = $arr[$i];
44+
else
45+
$leftArray[] = $arr[$i];
46+
}
47+
$leftArray = quickSort($leftArray);
48+
$leftArray[] = $middle;
49+
50+
$rightArray = quickSort($rightArray);
51+
return array_merge($leftArray, $rightArray);
52+
}
53+
```
54+

07.heapSort.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# 堆排序
2+
3+
堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。堆排序可以说是一种利用堆的概念来排序的选择排序。分为两种方法:
4+
5+
1. 大顶堆:每个节点的值都大于或等于其子节点的值,在堆排序算法中用于升序排列;
6+
2. 小顶堆:每个节点的值都小于或等于其子节点的值,在堆排序算法中用于降序排列;
7+
8+
堆排序的平均时间复杂度为 Ο(nlogn)。
9+
10+
11+
## 1. 算法步骤
12+
13+
1. 创建一个堆 H[0……n-1]
14+
15+
2. 把堆首(最大值)和堆尾互换;
16+
17+
3. 把堆的尺寸缩小 1,并调用 shift_down(0),目的是把新的数组顶端数据调整到相应位置;
18+
19+
4. 重复步骤 2,直到堆的尺寸为 1。
20+
21+
22+
## 2. 动图演示
23+
24+
![动图演示](res/heapSort.gif)
25+
26+
27+
## 3. PHP 代码实现
28+
29+
```php
30+
function buildMaxHeap(&$arr)
31+
{
32+
global $len;
33+
for ($i = floor($len/2); $i >= 0; $i--) {
34+
heapify($arr, $i);
35+
}
36+
}
37+
38+
function heapify(&$arr, $i)
39+
{
40+
global $len;
41+
$left = 2 * $i + 1;
42+
$right = 2 * $i + 2;
43+
$largest = $i;
44+
45+
if ($left < $len && $arr[$left] > $arr[$largest]) {
46+
$largest = $left;
47+
}
48+
49+
if ($right < $len && $arr[$right] > $arr[$largest]) {
50+
$largest = $right;
51+
}
52+
53+
if ($largest != $i) {
54+
swap($arr, $i, $largest);
55+
heapify($arr, $largest);
56+
}
57+
}
58+
59+
function swap(&$arr, $i, $j)
60+
{
61+
$temp = $arr[$i];
62+
$arr[$i] = $arr[$j];
63+
$arr[$j] = $temp;
64+
}
65+
66+
function heapSort($arr) {
67+
global $len;
68+
$len = count($arr);
69+
buildMaxHeap($arr);
70+
for ($i = count($arr) - 1; $i > 0; $i--) {
71+
swap($arr, 0, $i);
72+
$len--;
73+
heapify($arr, 0);
74+
}
75+
return $arr;
76+
}
77+
```

0 commit comments

Comments
 (0)