数据结构之冒泡排序---PHP版

最近在复习数据结构,就写一写博客来记录一下自己学习的路程。

一、冒泡排序很形象的就是最小的数字不断往上冒泡,每冒泡一次最上面的数字就是最小的,这个过程很像在水里冒泡一样,所以就叫冒泡算法。

如上图所示,这是经过了一次冒泡之后,2的位置从4变化到了1。所谓冒泡排序,最主要的思想就是两两比较,大的在下面小的在上面,这个过程也就是冒泡的过程。之后的冒泡过程也类似。经过6次冒泡,则成功将上面的集合变成有序集合。以下我用PHP代码来实现一下(为啥用PHP,因为我坚信PHP是世界上最好的语言~~~有点没底气哈哈哈哈)

代码1:

<?php

function maopao(&$list)
{

    $count = count($list);
    for ($i = 0; $i < $count; $i++) { //每循环一次就是一次冒泡的过程
        for ($j = $count – 1; $j > $i; $j–) {
            if ($list[$j – 1] > $list[$j]) {
                swap($list[$j – 1], $list[$j]);
            }
        }
    }
}
function swap(&$one, &$two)
{
    $tmp = $one;
    $one = $two;
    $two = $tmp;
}

?>

输入:输入一个数组集合 (不考虑非法输入)  输出:一个有序的数组

 

优化:我们仔细想一下,如果要排序的集合本身就比较有序,那冒泡排序算法是不是依然进行n次冒泡进行比较,只是不交换数据而已,这样子的话就做了很多无用功,我们是不是可以考虑在数据不交换的时候就停止比较了呢?因此,我们可以考虑添加一个标志位,在进行比较的时候如果不交换数据就置为true,这样就可以控制在数据不交换的时候就不进行比较了。以下是PHP实现

代码2:

<?php

function maopao(&$list)
{

   $count = count($list);

    static $flag = true;
    for ($i = 0; $i < $count && $flag; $i++) { //每循环一次就是一次冒泡的过程

        $flag = false;
        for ($j = $count – 1; $j > $i; $j–) {
            if ($list[$j – 1] > $list[$j]) {
                swap($list[$j – 1], $list[$j]);

                $flag = true;
            }
        }
    }
    return $list;
}
function swap(&$one, &$two)
{
    $tmp = $one;
    $one = $two;
    $two = $tmp;
}

?>

只要添加一个标志位来判断它是否已经有序了,是否需要继续冒泡,就可以减少不必要的比较,在性能方面还是提升了不少。这种性能在数据量比较大的时候还是能够体现出来的。

时间复杂度:最好的情况下(在集合本身已经有序的情况下)冒泡排序只需要比较n-1次即可

最坏的情况下(在集合本身完全逆序的情况下)冒泡排序需要比较1+2+3+4+....n-1=n*(n-1)/2次

所以冒泡排序的时间复杂度为O(n²),排序是稳定的

总结

冒泡排序很形象地就是小的数字不断往上冒泡,最主要的思想就是两两交换,大的往下沉小的往上冒泡,每次冒泡最小的数字都冒泡到顶端。考虑到集合本身有序的情况,可以将有序之后做一些标识停止冒泡,这样可以提升效率。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章