-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathquickSort.php
129 lines (121 loc) · 3.34 KB
/
quickSort.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<?php
/**
* Created by PhpStorm.
* User: peteryan
* Date: 2018/1/16
* Time: 13:47
*/
include_once("./Common.php");
$arr = [2,4,100,78,89,59,40,29,100];
$length = count($arr);
var_dump('sort before', $arr);
quickSort($arr, $length);
var_dump('sort after', $arr);
/**
*
* 快速排序,在需要排序的的数列中选取一个枢纽元,然后根据枢纽元将数列分为左右两部分,左边部分元素都小于枢纽元,右边部分元素都大于枢纽元,然后再分别对左右两部分分别递归调用,进行排序
*
*/
/**
* 入口
*
* @param $arr
* @param $length
*/
function quickSort(&$arr, $length) {
qSort($arr, 0, $length - 1);
}
/**
* 快排核心
*
* @param $arr
* @param $startIndex
* @param $endIndex
*/
function qSort(&$arr, $startIndex, $endIndex) {
if ($startIndex < $endIndex) {
if (false && $endIndex - $startIndex + 1 <= 3) {
selectSort($arr, $startIndex, $endIndex);
} else {
$pivot = median3($arr, $startIndex, $endIndex);
$i = $startIndex;
$j = $endIndex - 1;
while (true) {
while ($i < $j && Common::compare($arr[$i], $pivot) <= 0) {
$i++;
}
while ($i < $j && Common::compare($arr[$j], $pivot) >= 0) {
$j--;
}
if ($i < $j) {
Common::swap($arr[$i], $arr[$j]);
} else {
Common::swap($arr[$i], $arr[$endIndex - 1]);
break;
}
}
// $pivot = $arr[$startIndex];
// $i = $startIndex;
// $j = $endIndex;
// while ($i < $j) {
// while ($i < $j && Common::compare($arr[$j], $pivot) >= 0) {
// $j--;
// }
// $arr[$i] = $arr[$j];// 小的忘左边扔
// while ($i < $j && Common::compare($arr[$i], $pivot) <= 0) {
// $i++;
// }
// $arr[$j] = $arr[$i];// 大的忘右边扔
// }
// $arr[$i] = $pivot;
qSort($arr, $startIndex, $i - 1);
qSort($arr, $i + 1, $endIndex);
}
}
}
/**
*选取枢纽元,三数中值
*
* @param $arr
* @param $start
* @param $end
* @return mixed
*/
function median3(&$arr, $start, $end) {
$median = floor(($start + $end)/2);
if ($arr[$start] > $arr[$median]) {
Common::swap($arr[$start], $arr[$end]);
}
if ($arr[$start] > $arr[$end]) {
Common::swap($arr[$start], $arr[$end]);
}
if ($arr[$median] > $arr[$end]) {
Common::swap($arr[$median], $arr[$end]);
}
Common::swap($arr[$median], $arr[$end -1]);
return $arr[$end -1];
}
/**
* 指定索引区间选择排序
*
* @param $arr
* @param $startIndex
* @param $endIndex
*/
function selectSort(&$arr, $startIndex, $endIndex) {
if ($startIndex < $endIndex) {
for ($i = $startIndex; $i < $endIndex; $i++) {
$k = $i;
for ($j = $i + 1; $j <= $endIndex; $j++) {
if (Common::compare($arr[$k], $arr[$j]) > 0) {
$k = $j;
}
}
if ($k != $i) {
$tmp = $arr[$k];
$arr[$k] = $arr[$i];
$arr[$i] = $tmp;
}
}
}
}