Skip to content

Commit 02d596c

Browse files
committed
fix: fix this MergeSort 🐳
1 parent ac0619a commit 02d596c

File tree

3 files changed

+75
-73
lines changed

3 files changed

+75
-73
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
│ │ └── 快速查找
2828
│ │
2929
│ └── Other 其他
30+
│ └── BigSmallReplace.php Hello World 输出 Olleh Dlrow
3031
3132
├──LICENSE
3233
└──README.md

package/Other/BigSmallReplace.php

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,6 @@
77
* @date 2017/8/12
88
* @license Mozilla
99
*/
10-
//class BigSmallReplace
11-
//{
12-
// public function __construct( $requireStr )
13-
// {
14-
// $b = str_split($requireStr);
15-
// $c = [];
16-
// foreach ( $b as &$v ) {
17-
// if ( ord($v) > 64 && ord($v) < 91 ) {
18-
// $c[] = strtolower($v);
19-
// } else if ( ord($v) > 96 && ord($v) < 123 ) {
20-
// $c[] = strtoupper($v);
21-
// }
22-
// }
23-
// $d = implode('', $c);
24-
// echo $d;
25-
// }
26-
//}
27-
//// 大写专为小写小写转为大写
28-
//new BigSmallReplace('aBcDeFgHiJkLmNoPqRsTuVwXyZ');
29-
3010

3111
/**
3212
* segmentFault: https://segmentfault.com/q/1010000010627229
@@ -36,7 +16,7 @@
3616
* @param $str
3717
* @return string
3818
*/
39-
function EspecialStrrev( $str )
19+
function BigSmallReplace( $str )
4020
{
4121
// Cutting words
4222
$first = preg_split("/[\s]+/", $str);
@@ -58,7 +38,7 @@ function EspecialStrrev( $str )
5838
return implode(' ',$result);
5939
}
6040

61-
var_dump(EspecialStrrev('Hello World'));
41+
var_dump(BigSmallReplace('Hello World'));
6242
// Olleh Dlrow
6343

6444

package/Sort/MergeSort.php

Lines changed: 72 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<?php
2+
23
/**
34
* @example 归并排序
45
* @author ShaoWei Pu <[email protected]>
@@ -13,63 +14,83 @@
1314
* 归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,
1415
* 最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]
1516
*/
16-
17-
$arrStoreList = array(3,2,4,1,5);
18-
//$sort = new Merge_sort();
19-
//$sort->stableSort($arrStoreList, function ($a, $b) { // function ($a, $b)匿名函数
20-
// return $a < $b;
21-
//});
22-
23-
//静态调用方式也行
24-
Merge_sort:: stableSort($arrStoreList, function ($a, $b) {
25-
return $a < $b;
26-
});
27-
print_r($arrStoreList);
28-
29-
class Merge_sort{
30-
31-
public static function stableSort(&$array, $cmp_function = 'strcmp') {
32-
33-
//使用合并排序
34-
self::mergeSort($array, $cmp_function);
35-
return;
17+
class MergeSort
18+
{
19+
/**
20+
* MergeSort constructor.
21+
* 是开始递归函数的一个驱动函数
22+
*
23+
* @param array $arr 待排序的数组
24+
*/
25+
public function __construct(array $arr)
26+
{
27+
$len = count($arr);//求得数组长度
28+
$this->mSort($arr, 0, $len - 1);
29+
var_dump($arr);
3630
}
37-
public static function mergeSort(&$array, $cmp_function = 'strcmp') {
38-
// Arrays of size < 2 require no action.
39-
if (count($array) < 2) {
40-
return;
41-
}
42-
// Split the array in half
43-
$halfway = count($array) / 2;
44-
$array1 = array_slice($array, 0, $halfway);
45-
$array2 = array_slice($array, $halfway);
46-
// Recurse to sort the two halves
47-
self::mergeSort($array1, $cmp_function);
48-
self::mergeSort($array2, $cmp_function);
49-
// If all of $array1 is <= all of $array2, just append them.
50-
//array1 与 array2 各自有序;要整体有序,需要比较array1的最后一个元素和array2的第一个元素大小
51-
if (call_user_func($cmp_function, end($array1), $array2[0]) < 1) {
52-
$array = array_merge($array1, $array2);
5331

54-
return;
32+
/**
33+
* 实际实现归并排序的程序
34+
*
35+
* @param $arr array 需要排序的数组
36+
* @param $left int 子序列的左下标值
37+
* @param $right int 子序列的右下标值
38+
*/
39+
public function mSort(&$arr, $left, $right)
40+
{
41+
if ($left < $right) {
42+
//说明子序列内存在多余1个的元素,那么需要拆分,分别排序,合并
43+
//计算拆分的位置,长度/2 去整
44+
$center = floor(($left + $right) / 2);
45+
//递归调用对左边进行再次排序:
46+
$this->mSort($arr, $left, $center);
47+
//递归调用对右边进行再次排序
48+
$this->mSort($arr, $center + 1, $right);
49+
//合并排序结果
50+
$this->mergeArray($arr, $left, $center, $right);
5551
}
56-
// 将两个有序数组合并为一个有序数组:Merge the two sorted arrays into a single sorted array
57-
$array = array();
58-
$ptr1 = $ptr2 = 0;
59-
while ($ptr1 < count($array1) && $ptr2 < count($array2)) {
60-
if (call_user_func($cmp_function, $array1[$ptr1], $array2[$ptr2]) < 1) {
61-
$array[] = $array1[$ptr1++];
52+
}
53+
54+
/**
55+
* 将两个有序数组合并成一个有序数组
56+
*
57+
* @param &$arr , 待排序的所有元素
58+
* @param $left , 排序子数组A的开始下标
59+
* @param $center , 排序子数组A与排序子数组B的中间下标,也就是数组A的结束下标
60+
* @param $right , 排序子数组B的结束下标(开始为$center+1)
61+
*/
62+
public function mergeArray(&$arr, $left, $center, $right)
63+
{
64+
//设置两个起始位置标记
65+
$a_i = $left;
66+
$b_i = $center + 1;
67+
$temp = [];
68+
69+
while ($a_i <= $center && $b_i <= $right){
70+
//当数组A和数组B都没有越界时
71+
if ($arr[ $a_i ] < $arr[ $b_i ]) {
72+
$temp[] = $arr[ $a_i++ ];
6273
} else {
63-
$array[] = $array2[$ptr2++];
74+
$temp[] = $arr[ $b_i++ ];
6475
}
6576
}
66-
// Merge the remainder
67-
while ($ptr1 < count($array1)) {
68-
$array[] = $array1[$ptr1++];
77+
//判断 数组A内的元素是否都用完了,没有的话将其全部插入到C数组内:
78+
while ($a_i <= $center){
79+
$temp[] = $arr[ $a_i++ ];
6980
}
70-
while ($ptr2 < count($array2)) {
71-
$array[] = $array2[$ptr2++];
81+
//判断 数组B内的元素是否都用完了,没有的话将其全部插入到C数组内:
82+
while ($b_i <= $right){
83+
$temp[] = $arr[ $b_i++ ];
84+
}
85+
86+
//将$arrC内排序好的部分,写入到$arr内:
87+
for ($i = 0, $len = count($temp); $i < $len; $i++){
88+
$arr[ $left + $i ] = $temp[ $i ];
7289
}
73-
return;
7490
}
75-
}
91+
}
92+
93+
//do some test:
94+
new mergeSort([4, 7, 6, 3, 9, 5, 8]);
95+
96+

0 commit comments

Comments
 (0)