From 32804029a9f073ec88c9f7b72a88f43c38b6dfef Mon Sep 17 00:00:00 2001 From: weilong Date: Tue, 3 Apr 2018 15:21:57 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0PHP=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=8F=8A=E6=B5=8B=E8=AF=95=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 1.bubbleSort.md | 19 +++ 10.radixSort.md | 37 ++++++ 2.selectionSort.md | 21 +++ 3.insertionSort.md | 19 +++ 4.shellSort.md | 24 ++++ 5.mergeSort.md | 37 ++++++ 6.quickSort.md | 25 ++++ 7.heapSort.md | 52 ++++++++ 8.countingSort.md | 29 +++++ 9.bucketSort.md | 42 ++++++ src/phpSortTest.php | 304 ++++++++++++++++++++++++++++++++++++++++++++ 11 files changed, 609 insertions(+) create mode 100644 src/phpSortTest.php diff --git a/1.bubbleSort.md b/1.bubbleSort.md index 621314f..78c3b83 100644 --- a/1.bubbleSort.md +++ b/1.bubbleSort.md @@ -110,3 +110,22 @@ public class BubbleSort implements IArraySort { } } ``` + +## 9. PHP 代码实现 + +```php +function bubbleSort($arr) +{ + $len = count($arr); + for ($i = 0; $i < $len - 1; $i++) { + for ($j = 0; $j < $len - 1 - $i; $j++) { + if ($arr[$j] > $arr[$j+1]) { + $tmp = $arr[$j]; + $arr[$j] = $arr[$j+1]; + $arr[$j+1] = $tmp; + } + } + } + return $arr; +} +``` diff --git a/10.radixSort.md b/10.radixSort.md index 39b0a64..0bcd341 100644 --- a/10.radixSort.md +++ b/10.radixSort.md @@ -133,3 +133,40 @@ public class RadixSort implements IArraySort { } } ``` + +## 5. PHP 代码实现 + +```php +function radixSort($arr, $maxDigit = null) +{ + if ($maxDigit === null) { + $maxDigit = max($arr); + } + $counter = []; + for ($i = 0; $i < $maxDigit; $i++) { + for ($j = 0; $j < count($arr); $j++) { + preg_match_all('/\d/', (string) $arr[$j], $matches); + $numArr = $matches[0]; + $lenTmp = count($numArr); + $bucket = array_key_exists($lenTmp - $i - 1, $numArr) + ? intval($numArr[$lenTmp - $i - 1]) + : 0; + if (!array_key_exists($bucket, $counter)) { + $counter[$bucket] = []; + } + $counter[$bucket][] = $arr[$j]; + } + $pos = 0; + for ($j = 0; $j < count($counter); $j++) { + $value = null; + if ($counter[$j] !== null) { + while (($value = array_shift($counter[$j])) !== null) { + $arr[$pos++] = $value; + } + } + } + } + + return $arr; +} +``` \ No newline at end of file diff --git a/2.selectionSort.md b/2.selectionSort.md index ae7350f..103830e 100644 --- a/2.selectionSort.md +++ b/2.selectionSort.md @@ -105,3 +105,24 @@ public class SelectionSort implements IArraySort { } } ``` + +## 7. PHP 代码实现 + +```php +function selectionSort($arr) +{ + $len = count($arr); + for ($i = 0; $i < $len - 1; $i++) { + $minIndex = $i; + for ($j = $i + 1; $j < $len; $j++) { + if ($arr[$j] < $arr[$minIndex]) { + $minIndex = $j; + } + } + $temp = $arr[$i]; + $arr[$i] = $arr[$minIndex]; + $arr[$minIndex] = $temp; + } + return $arr; +} +``` diff --git a/3.insertionSort.md b/3.insertionSort.md index 71beec9..c828cb3 100644 --- a/3.insertionSort.md +++ b/3.insertionSort.md @@ -99,3 +99,22 @@ public class InsertSort implements IArraySort { } } ``` + +## 7. PHP 代码实现 + +```php +function insertionSort($arr) +{ + $len = count($arr); + for ($i = 1; $i < $len; $i++) { + $preIndex = $i - 1; + $current = $arr[$i]; + while($preIndex >= 0 && $arr[$preIndex] > $current) { + $arr[$preIndex+1] = $arr[$preIndex]; + $preIndex--; + } + $arr[$preIndex+1] = $current; + } + return $arr; +} +``` diff --git a/4.shellSort.md b/4.shellSort.md index c96d8b7..187ac0e 100644 --- a/4.shellSort.md +++ b/4.shellSort.md @@ -120,3 +120,27 @@ public class ShellSort implements IArraySort { } } ``` + +## 6. PHP 代码实现 + +```php +function shellSort($arr) +{ + $len = count($arr); + $temp = 0; + $gap = 1; + while($gap < $len / 3) { + $gap = $gap * 3 + 1; + } + for ($gap; $gap > 0; $gap = floor($gap / 3)) { + for ($i = $gap; $i < $len; $i++) { + $temp = $arr[$i]; + for ($j = $i - $gap; $j >= 0 && $arr[$j] > $temp; $j -= $gap) { + $arr[$j+$gap] = $arr[$j]; + } + $arr[$j+$gap] = $temp; + } + } + return $arr; +} +``` diff --git a/5.mergeSort.md b/5.mergeSort.md index 8394ab5..bf0de32 100644 --- a/5.mergeSort.md +++ b/5.mergeSort.md @@ -186,3 +186,40 @@ public class MergeSort implements IArraySort { } ``` + +## 8. PHP 代码实现 + +```php +function mergeSort($arr) +{ + $len = count($arr); + if ($len < 2) { + return $arr; + } + $middle = floor($len / 2); + $left = array_slice($arr, 0, $middle); + $right = array_slice($arr, $middle); + return merge(mergeSort($left), mergeSort($right)); +} + +function merge($left, $right) +{ + $result = []; + + while (count($left) > 0 && count($right) > 0) { + if ($left[0] <= $right[0]) { + $result[] = array_shift($left); + } else { + $result[] = array_shift($right); + } + } + + while (count($left)) + $result[] = array_shift($left); + + while (count($right)) + $result[] = array_shift($right); + + return $result; +} +``` \ No newline at end of file diff --git a/6.quickSort.md b/6.quickSort.md index 497f973..28ad477 100644 --- a/6.quickSort.md +++ b/6.quickSort.md @@ -228,3 +228,28 @@ public class QuickSort implements IArraySort { } ``` + +## 8. PHP 代码实现 + +```php +function quickSort($arr) +{ + if (count($arr) <= 1) + return $arr; + $middle = $arr[0]; + $leftArray = array(); + $rightArray = array(); + + for ($i = 1; $i < count($arr); $i++) { + if ($arr[$i] > $middle) + $rightArray[] = $arr[$i]; + else + $leftArray[] = $arr[$i]; + } + $leftArray = quickSort($leftArray); + $leftArray[] = $middle; + + $rightArray = quickSort($rightArray); + return array_merge($leftArray, $rightArray); +} +``` diff --git a/7.heapSort.md b/7.heapSort.md index 43d522c..35b24ec 100644 --- a/7.heapSort.md +++ b/7.heapSort.md @@ -203,3 +203,55 @@ public class HeapSort implements IArraySort { } ``` + +## 7. PHP 代码实现 + +```php +function buildMaxHeap(&$arr) +{ + global $len; + for ($i = floor($len/2); $i >= 0; $i--) { + heapify($arr, $i); + } +} + +function heapify(&$arr, $i) +{ + global $len; + $left = 2 * $i + 1; + $right = 2 * $i + 2; + $largest = $i; + + if ($left < $len && $arr[$left] > $arr[$largest]) { + $largest = $left; + } + + if ($right < $len && $arr[$right] > $arr[$largest]) { + $largest = $right; + } + + if ($largest != $i) { + swap($arr, $i, $largest); + heapify($arr, $largest); + } +} + +function swap(&$arr, $i, $j) +{ + $temp = $arr[$i]; + $arr[$i] = $arr[$j]; + $arr[$j] = $temp; +} + +function heapSort($arr) { + global $len; + $len = count($arr); + buildMaxHeap($arr); + for ($i = count($arr) - 1; $i > 0; $i--) { + swap($arr, 0, $i); + $len--; + heapify($arr, 0); + } + return $arr; +} +``` \ No newline at end of file diff --git a/8.countingSort.md b/8.countingSort.md index b0f17e5..efabf9c 100644 --- a/8.countingSort.md +++ b/8.countingSort.md @@ -126,3 +126,32 @@ public class CountingSort implements IArraySort { } ``` + +## 6. PHP 代码实现 + +```php +function countingSort($arr, $maxValue = null) +{ + if ($maxValue === null) { + $maxValue = max($arr); + } + for ($m = 0; $m < $maxValue + 1; $m++) { + $bucket[] = null; + } + + $arrLen = count($arr); + for ($i = 0; $i < $arrLen; $i++) { + if (!array_key_exists($arr[$i], $bucket)) { + $bucket[$arr[$i]] = 0; + } + $bucket[$arr[$i]]++; + } + + $sortedIndex = 0; + foreach ($bucket as $key => $len) { + if ($len !== null) $arr[$sortedIndex++] = $key; + } + + return $arr; +} +``` \ No newline at end of file diff --git a/9.bucketSort.md b/9.bucketSort.md index e2e4aa6..bd76a63 100644 --- a/9.bucketSort.md +++ b/9.bucketSort.md @@ -131,3 +131,45 @@ public class BucketSort implements IArraySort { } ``` + +## 5. PHP 代码实现 + +```php +function bucketSort($arr, $bucketSize = 5) +{ + if (count($arr) === 0) { + return $arr; + } + + $minValue = $arr[0]; + $maxValue = $arr[0]; + for ($i = 1; $i < count($arr); $i++) { + if ($arr[$i] < $minValue) { + $minValue = $arr[$i]; + } else if ($arr[$i] > $maxValue) { + $maxValue = $arr[$i]; + } + } + + $bucketCount = floor(($maxValue - $minValue) / $bucketSize) + 1; + $buckets = array(); + for ($i = 0; $i < count($buckets); $i++) { + $buckets[$i] = []; + } + + for ($i = 0; $i < count($arr); $i++) { + $buckets[floor(($arr[$i] - $minValue) / $bucketSize)][] = $arr[$i]; + } + + $arr = array(); + for ($i = 0; $i < count($buckets); $i++) { + $bucketTmp = $buckets[$i]; + sort($bucketTmp); + for ($j = 0; $j < count($bucketTmp); $j++) { + $arr[] = $bucketTmp[$j]; + } + } + + return $arr; +} +``` \ No newline at end of file diff --git a/src/phpSortTest.php b/src/phpSortTest.php new file mode 100644 index 0000000..4fc59d5 --- /dev/null +++ b/src/phpSortTest.php @@ -0,0 +1,304 @@ + + * + * 主要参考了 JS 的写法及网上的一些写法。 + * + * Require: php -v >= 5.4 + * Test: php phpSortTest.php + */ + +function sortTest($func, $total = 5000) +{ + global $arr; + if (empty($arr)) { + $arr = range(1, $total); + echo "Verify sort md5: ", substr(md5(json_encode($arr)), 0, 8), "\r\n"; + shuffle($arr); + } + list($m1, $n1) = explode(' ', microtime()); + $res = $func($arr); + list($m2, $n2) = explode(' ', microtime()); + $time = round(($m2 - $m1) + ($n2 - $n1), 6); + echo " $func {$time}s " . substr(md5(json_encode($res)), 0, 8) . "\r\n"; +} + +function bubbleSort($arr) +{ + $len = count($arr); + for ($i = 0; $i < $len; $i++) { + for ($j = 0; $j < $len - 1 - $i; $j++) { + if ($arr[$j] > $arr[$j+1]) { + $tmp = $arr[$j]; + $arr[$j] = $arr[$j+1]; + $arr[$j+1] = $tmp; + } + } + } + return $arr; +} + +function selectionSort($arr) +{ + $len = count($arr); + for ($i = 0; $i < $len - 1; $i++) { + $minIndex = $i; + for ($j = $i + 1; $j < $len; $j++) { + if ($arr[$j] < $arr[$minIndex]) { + $minIndex = $j; + } + } + $temp = $arr[$i]; + $arr[$i] = $arr[$minIndex]; + $arr[$minIndex] = $temp; + } + return $arr; +} + +function insertionSort($arr) +{ + $len = count($arr); + for ($i = 1; $i < $len; $i++) { + $preIndex = $i - 1; + $current = $arr[$i]; + while($preIndex >= 0 && $arr[$preIndex] > $current) { + $arr[$preIndex+1] = $arr[$preIndex]; + $preIndex--; + } + $arr[$preIndex+1] = $current; + } + return $arr; +} + +function shellSort($arr) +{ + $len = count($arr); + $temp = 0; + $gap = 1; + while($gap < $len / 3) { + $gap = $gap * 3 + 1; + } + for ($gap; $gap > 0; $gap = floor($gap / 3)) { + for ($i = $gap; $i < $len; $i++) { + $temp = $arr[$i]; + for ($j = $i - $gap; $j >= 0 && $arr[$j] > $temp; $j -= $gap) { + $arr[$j+$gap] = $arr[$j]; + } + $arr[$j+$gap] = $temp; + } + } + return $arr; +} + +function mergeSort($arr) +{ + $len = count($arr); + if ($len < 2) { + return $arr; + } + $middle = floor($len / 2); + $left = array_slice($arr, 0, $middle); + $right = array_slice($arr, $middle); + return merge(mergeSort($left), mergeSort($right)); +} + +function merge($left, $right) +{ + $result = []; + + while (count($left) > 0 && count($right) > 0) { + if ($left[0] <= $right[0]) { + $result[] = array_shift($left); + } else { + $result[] = array_shift($right); + } + } + + while (count($left)) + $result[] = array_shift($left); + + while (count($right)) + $result[] = array_shift($right); + + return $result; +} + +function quickSort($arr) +{ + if (count($arr) <= 1) + return $arr; + $middle = $arr[0]; + $leftArray = array(); + $rightArray = array(); + + for ($i = 1; $i < count($arr); $i++) { + if ($arr[$i] > $middle) + $rightArray[] = $arr[$i]; + else + $leftArray[] = $arr[$i]; + } + $leftArray = quickSort($leftArray); + $leftArray[] = $middle; + + $rightArray = quickSort($rightArray); + return array_merge($leftArray, $rightArray); +} + + +function buildMaxHeap(&$arr) +{ + global $len; + for ($i = floor($len/2); $i >= 0; $i--) { + heapify($arr, $i); + } +} + +function heapify(&$arr, $i) +{ + global $len; + $left = 2 * $i + 1; + $right = 2 * $i + 2; + $largest = $i; + + if ($left < $len && $arr[$left] > $arr[$largest]) { + $largest = $left; + } + + if ($right < $len && $arr[$right] > $arr[$largest]) { + $largest = $right; + } + + if ($largest != $i) { + swap($arr, $i, $largest); + heapify($arr, $largest); + } +} + +function swap(&$arr, $i, $j) +{ + $temp = $arr[$i]; + $arr[$i] = $arr[$j]; + $arr[$j] = $temp; +} + +function heapSort($arr) { + global $len; + $len = count($arr); + buildMaxHeap($arr); + for ($i = count($arr) - 1; $i > 0; $i--) { + swap($arr, 0, $i); + $len--; + heapify($arr, 0); + } + return $arr; +} + +function countingSort($arr, $maxValue = null) +{ + if ($maxValue === null) { + $maxValue = max($arr); + } + for ($m = 0; $m < $maxValue + 1; $m++) { + $bucket[] = null; + } + + $arrLen = count($arr); + for ($i = 0; $i < $arrLen; $i++) { + if (!array_key_exists($arr[$i], $bucket)) { + $bucket[$arr[$i]] = 0; + } + $bucket[$arr[$i]]++; + } + + $sortedIndex = 0; + foreach ($bucket as $key => $len) { + if ($len !== null) $arr[$sortedIndex++] = $key; + } + + return $arr; +} + +function bucketSort($arr, $bucketSize = 5) +{ + if (count($arr) === 0) { + return $arr; + } + + $minValue = $arr[0]; + $maxValue = $arr[0]; + for ($i = 1; $i < count($arr); $i++) { + if ($arr[$i] < $minValue) { + $minValue = $arr[$i]; + } else if ($arr[$i] > $maxValue) { + $maxValue = $arr[$i]; + } + } + + $bucketCount = floor(($maxValue - $minValue) / $bucketSize) + 1; + $buckets = array(); + for ($i = 0; $i < count($buckets); $i++) { + $buckets[$i] = []; + } + + for ($i = 0; $i < count($arr); $i++) { + $buckets[floor(($arr[$i] - $minValue) / $bucketSize)][] = $arr[$i]; + } + + $arr = array(); + for ($i = 0; $i < count($buckets); $i++) { + $bucketTmp = $buckets[$i]; + sort($bucketTmp); + for ($j = 0; $j < count($bucketTmp); $j++) { + $arr[] = $bucketTmp[$j]; + } + } + + return $arr; +} + +function radixSort($arr, $maxDigit = null) +{ + if ($maxDigit === null) { + $maxDigit = max($arr); + } + $counter = []; + for ($i = 0; $i < $maxDigit; $i++) { + for ($j = 0; $j < count($arr); $j++) { + preg_match_all('/\d/', (string) $arr[$j], $matches); + $numArr = $matches[0]; + $lenTmp = count($numArr); + $bucket = array_key_exists($lenTmp - $i - 1, $numArr) + ? intval($numArr[$lenTmp - $i - 1]) + : 0; + if (!array_key_exists($bucket, $counter)) { + $counter[$bucket] = []; + } + $counter[$bucket][] = $arr[$j]; + } + $pos = 0; + for ($j = 0; $j < count($counter); $j++) { + $value = null; + if ($counter[$j] !== null) { + while (($value = array_shift($counter[$j])) !== null) { + $arr[$pos++] = $value; + } + } + } + } + + return $arr; +} + +$total = 2000; + +sortTest('bubbleSort', $total); +sortTest('selectionSort', $total); +sortTest('insertionSort', $total); +sortTest('shellSort', $total); +sortTest('mergeSort', $total); +sortTest('quickSort', $total); +sortTest('heapSort', $total); +sortTest('countingSort', $total); +sortTest('bucketSort', $total); +sortTest('radixSort', $total);