手记

常用的排序算法(三)--冒泡排序(PHP实现)

常用的排序算法系列


冒泡排序

这期讲个比较简单实现的排序算法,在数据规模较小的时候,比如数组长度可能不到5000之类的(不同语言有不同差异),用简单的算法可能会比复杂算法更优。

因为简单算法在规模小的情况下,表现出来的劣势并不明显,复杂算法也可能只是快那么零点零几秒,而复杂算法多数是需要占用更多的空间资源的,因此简单场景下,我们不妨就用简单的排序算法。

冒泡排序

这个是初学者多数接触到的第一个算法。这个算法很简单,我当初最开始学的时候,记的是 “两个循环,相邻比较”,然后把这个算法记住的。

冒泡排序法的本质,就是逐个用相邻比较交换的方法,从数组头开始检查到待检查的数组尾。每一轮排序结束之后,尾巴就会多一个排好的数,就像冒泡一样把这个数冒了出来。

比如我们手里有一个数组a
[5,8,6,4,12,5]
现在需要把它从小到大排序,那么我们就开始逐个相邻比较交换,相邻的数据里面,如果是大的在前,小的在后,我们就交换一下。

首先,a[0]=5 < a[1] =8, 不理
a[1] > a[2] 交换一下两个数
变成了
[5,6,8,4,12,5]

继续检查
a[2] > a[3],交换一下两个数
变成了
[5,6,4,8,12,5]

a[3] < a[4] ,不理
a[4] > a[5], 交换一下
变成了
[5,6,4,8,5,12]

这时候,我们完成了第一轮的排序,成功的冒出了一个最大的数【12】,因此我们第二轮的排序就不需要去管这个最末已经冒出来的数据了。

假设我们的数组长度是 n,第一位是0,那么数组最后一位就是 n-1,倒数第二位是 n-2 。

第一轮,我们两两比较的前数,是从 0 一直到 n-2 的,也就是从第一位到倒数第二位,而后数是从1一直到 n-1,两个是相邻的关系。

第二轮的前数就会从0 一直到 n-3 (因为前一轮冒出了一个), 后数则一直等于前数加1。

第三轮的前数就会从0 一直到 n-4 (前几轮一共冒出了两个)

如此递推,那么最后一层就是 从0 一直到1,只比较一次,

这整个过程,一共有n-1轮,根据上面的递推关系会发现,第 i 轮,前数都是从 0 到 n -1- i 的,所以这里面就可以用两个循环来处理。

外层循环令变量为 i ,是从0 遍历到 n-1 ,也就是表示这里面的 n-1 轮。

内层循环令变量为 j ,是从0 遍历到 n-1-i ,也就是表示每一轮这里面的逐个前后两个相邻数进行比较。

在内层循环里,如果 a[j] > a[j+1], (目的是从小排到大的情况),说明应该把小数放到更前面,所以交换这两个数。

这个就是冒泡排序的全部过程了。

实现代码

/** 冒泡排序
 * @param array $ar
 * @param null $len
 */
function bubble(array & $ar, $len = null)
{
    if ($len === null) {
        $len = sizeof($ar);
    }

    for ($i = 0; $i < $len-1; $i++) {
        for ($j = 0; $j < $len-$i-1; $j++) {

            if ($ar[$j] > $ar[$j+1]) {//swap
                echo "swap [$j]--[";
                echo $j+1;
                echo ']';

                echo "<br/>";

                $t = $ar[$j];
                $ar[$j] = $ar[$j+1];
                $ar[$j+1] = $t;
            }

        }
        print_r(json_encode($ar));
        echo "<br/>";

    }

}
4人推荐
随时随地看视频
慕课网APP

热门评论

留给初学者一个小思考题,如果我想要每一轮的排序,有一个小的数冒到最前面来,请问需要怎么做呢?

查看全部评论