Toggle navigation
leo's blog
PHP
JavaScript
MySQL
Linux
瞎扯
冒泡排序的优化方案
PHP
2020-07-14 12:19:25
40
简介:
冒泡排序即整个过程像气泡一样往上升,对于给定的n个记录先从第一个记录开始依次与相邻的两个记录进行比较,当前面的记录大于后面的记录时交换位置,进行一轮比较后,n个记录中最大记录将位于第n个元素中。然后继续对前面的n-1个元素重复比较过程
## 冒泡排序分析 冒泡排序即整个过程像气泡一样往上升,对于给定的n个记录先从第一个记录开始依次与相邻的两个记录进行比较,当前面的记录大于后面的记录时交换位置,进行一轮比较后,n个记录中最大记录将位于第n个元素中。然后继续对前面的n-1个元素重复比较过程 ## 常规实现方式 ```php var_dump(maopao3([100,24,3,88,77,44])); function maopao($arr){ $j = 1; $len = count($arr); for ($i=1; $i <$len ; $i++) { for ($k=0; $k <$len-$i;$k++) { $j++; if($arr[$k] > $arr[$k+1]){ $tmp = $arr[$k+1]; $arr[$k+1] = $arr[$k]; $arr[$k] = $tmp; } } } echo '循环次数:'.$j.'<hr/>'; return $arr; } ``` 执行上面的结果虽然可以正常实现从小到大的排序,但是循环次数需要16次 ## 冒泡排序改进 对于每外侧循环一次完成后可以确定最后最大的元素在最后面,因此可以减少里层循环的次数进行优化 ```php var_dump(maopao2[100,24,3,88,77,44])); function maopao2($arr){ $j = 1;//记录循环次数 $len = count($arr); for ($i=1; $i <$len ; $i++) { $z=0;//记录已经正常排序了的次数 for ($k=0; $k <$len-$i-$z ; $k++) { $j++; $z++; if($arr[$k] > $arr[$k+1]){ $tmp = $arr[$k+1]; $arr[$k+1] = $arr[$k]; $arr[$k] = $tmp; } } } echo '循环次数:'.$j.'<hr/>'; return $arr; } ``` 上面的代码执行完毕排序正常,但是循环次数只需要10次,比起常规的冒泡排序优化 ## 双向冒泡 在前面两种冒泡排序方式中每一趟排序只能找到一个最大值或者一个最小值,所以考虑在每一趟循环中进行正向和反向两遍排序,那么一次就得到了最大值和最小值,从而可以将排序的此处减少将近一半 ```php var_dump(maopao3([100,24,3,88,77,44])); function maopao3($arr){ $low = 0;//记录最小值 $high = count($arr)-1;//设置初始的循环次数 $index = 1; while ($low<$high) { //正向冒泡找到最大值 for ($j=$low; $j <$high ; ++$j) { if($arr[$j] > $arr[$j+1]){ $tmp = $arr[$j]; $arr[$j] = $arr[$j+1]; $arr[$j+1] = $tmp; } } --$high;//设置high 将循环的次数前移一位 //反向冒泡找到最小值 for ($j=$high; $j >$low ; --$j) { $index++; if($arr[$j]<$arr[$j-1]){ $tmp = $arr[$j]; $arr[$j] = $arr[$j-1]; $arr[$j-1] = $tmp; } } ++$low; } echo $index; return $arr; } ``` 使用正反两次冒泡排序 只需要循环7次就可以得到正确的结果
Top