冒泡排序这么干
Posted 南北技术笔记
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了冒泡排序这么干相关的知识,希望对你有一定的参考价值。
感冒还是没好,也到周末了。后面会想总结一些mysql索引方面的东西,会牵扯到B+Tree(但是不懂)。所以先中断一下,穿插总结一下数据结构和常见的排序算法。
1.冒泡排序是一种很基本的排序算法,通过不停的比较相邻的两个元素,将值大的元素交换到右边(这种得到的结果是从小到大,如果你希望从大到小的话,将小的元素交换到右边即可),实现数据的排序操作。
2.思路:
第一次比较,比较第一个a1和第二个元素a2,如果a1>a2,交换a1和a2。
第二次比较,比较第二个a2和第三个元素a3,如果a3>a2,交换a2和a3.
......
比较倒数第二个和倒数第一个元素,得到最大的元素,放到右边。至此,我们得到了所有数组中的最大元素(此时最大元素是有序的),但是其他元素还是无序的。
我们重复上面的1234步骤,得到第二个最大的元素。这一轮比较,是不需要比较有序的数据的,因为第一轮比较,我们就知道了最后一个是最大的元素。
重复第5步,直到数据完全有序。
冒泡排序的逻辑上来说,将数据分成了无序和有序两部分,每次拿到无序的最大值后,无序的数据总数都减1,所以冒泡排序,越往后执行,需要比较的次数就越少,因为越往后,有序的数据越多,无序的数据越少。
3.举例:
要排序数组:[1,9,10,8,-4]
第一趟排序(总共进行了四次比较,结果[1,9,8,-4,10])
第一次比较:1和9比较,9大于1,不发生交换。[1,9,10,8,-4]
第二次比较:9和10比较,10大于9,不发生交换。[1,9,10,8,-4]
第三次比较:10和8比较,8小于10,发生交换。[1,9,8,10,-4]
第四次比较:10和-4比较,-4小于10,发生交换。[1,9,8,-4,10]
第二趟排序(进行三次比较,结果[1,8,-4,9,10],第一趟排序已经得到整个无序数组的最大值,所以沉到最下面的元素已经是有序的了)
第一次比较:1和9比较,9大于1,不发生交换。[1,9,8,-4,10]
第二次比较:9和8比较,8小于9,发生交换。[1,8,9,-4,10]
第三次比较:9和-4比较,-4小于9,发生交换。[1,8,-4,9,10]
第三趟排序(进行两次比较,得到[1,-4,8,9,10])
第一次比较:1和8比较,8大于1,不发生交换。[1,8,-4,9,10]
第二次比较:-4和8比较,-4小于8,发生交换。[1,-4,8,9,10]
第四趟排序(进行一次比较,得到[-4,1,8,9,10])
第一次比较:-4和1比较,-4小于1,发生交换。[-4,1,8,9,10]
4.算法分析
从上面排序流程,可以看到,对于一个包含N个元素的无序数组,总共需要进行N-1趟排序,假设每趟排序的参数为i,则每趟的比较次数为N-i,所以对于冒泡排序算法,可以通过双重循环来实现,外层循环控制需要排序的次数,内层循环控制需要相邻元素比较的次数。
5.算法实现
$arr = [1,9,10,8,-4];
$length = count($arr);
for ($i = 0; $i < $length - 1; $i++) {
for ($j = 0; $j < $length - $i - 1; $j++) {
if ($arr[$j] < $arr[$j + 1]) {
$temp = $arr[$j];
$arr[$j] = $arr[$j + 1];
$arr[$j + 1] = $temp;
}
}
}
print_r($arr);
6.冒泡排序的优点
冒泡排序,每次排序都会得到一个无序数组中最大(或最小)的元素,也可以理解冒泡排序将整个数组分成两个部分,无序和有序两部分,每次排序都会往有序的部分加入一个元素,无序的部分减少一个元素;所以冒泡排序越是执行到后面,需要比较的无序元素就越少,一定程度上减少了算法的量。
7.时间复杂度推算
我们以最坏的情况来计算,整个数组的元素完全是反序的,这种最坏的情况,每次比较之后,都需要进行一次元素的交换(一次交换需要三步)。
从第三步的例子中可以看出,对于一个包含N个元素的数组来说比较步数有一定的规律为:C(max) = 1+2+3+...+(N-1)=(n-1)*(n-1+1)/2。
所以总步数=C(max)*3。
对于时间复杂度来说,由最高项的情况下,我们只取最高项,所以冒泡排序的最差时间复杂度为O(n²)。
END
以上是关于冒泡排序这么干的主要内容,如果未能解决你的问题,请参考以下文章