排序算法 - 冒泡排序

- 1 min

数据结构与算法系列(八)

今天要给大家介绍的是基于选择的排序算法,常见基于选择的排序算法有冒泡排序、插入排序、选择排序、归并排序和快速排序,我们在选择排序算法的时候,通常会根据以下几个维度来考虑:

我们首先从冒泡排序开始。

冒泡排序只会操作相邻的两个数据。每次冒泡操作都会对相邻的两个元素进行比较,看是否满足大小关系要求,如果不满足就让它俩互换。一次冒泡会让至少一个元素移动到它应该在的位置,重复 n 次,就完成了 n 个数据的排序工作。

光看定义有点抽象,我们用图来演示,假设待排序数字是 4、5、6、3、2、1,第一次排序的流程是这样的:

看这个图的时候要结合定义一起看,否则也比较懵逼,当然如果你去 VisuAlgo 上看动态图的话就更形象了:VisuAlgo - 排序(冒泡排序, 选择排序, 插入排序, 归并排序, 快速排序, 计数排序, …,经过 n 次冒泡,最终完成排序(所谓冒泡,以升序来看,就是每次把待排序序列中的最大值插到已排序序列的最前面,这个过程就像冒泡一样):

重要的是理解冒泡排序的原理,懂了原理就是把这个排序过程翻译成代码而已,以下是 PHP 代码实现的冒泡排序:

<?php

/**
 * 冒泡排序实现函数(PHP)
 * @param $nums
 * @return mixed
 */
function bubble_sort($nums) {
    if (count($nums) <= 1) {
        return $nums;
    }

    for ($i = 0; $i < count($nums); $i++) {
        $flag = false;
        for ($j = 0; $j < count($nums) - $i - 1; $j++) {
            if ($nums[$j] > $nums[$j+1]) {
                list($nums[$j+1], $nums[$j]) = array($nums[$j], $nums[$j+1]);
                $flag = true;
            }
        }
        if (!$flag) {
            break;
        }
    }

    return $nums;
}

$nums = [4, 5, 6, 3, 2, 1];
$nums = bubble_sort($nums);
print_r($nums);

可以看到我们对冒泡排序有个小小的优化,就是当某一次遍历的时候发现没有需要交换的元素,则认为整个序列已经排序完成。最后我们来看下冒泡排序的性能和稳定性:

时间复杂度是 O(n^2),看起来性能并不是很好,所以我们在实践中基本不会选用冒泡算法。

rss facebook twitter github gitlab youtube mail spotify lastfm instagram linkedin google google-plus pinterest medium vimeo stackoverflow reddit quora quora