排序算法系列之(二)——冒泡排序名字最为形象的一个

前言

大约在上个冬季我给自己挖了一个坑(想要总结排序~~(>_<)~~),感觉把自己埋起来会暖和一点,可是大约一年过去了,埋的越来越深,却丝毫感觉不到暖意……被我的诗意打动了有没有,已经深深的折服了有没有,呵呵,我自己都不信!

还是继续来说说排序,距离上一篇排序总结《排序算法系列之(一)——选择排序清新脱俗的一面》2017-02-15 16:29已经过去了大半年的时间,代码越敲越多,但总结往往跟不上了,加油吧!

冒泡排序

那么言归正传,接下来我们请出今天的主角——冒泡排序。老规矩,我们不讲时间复杂度、不讲空间复杂度、不讲算法的优缺点,我们就来聊聊自己的理解,讲讲它为什么起了一个好名字——冒泡,话说这么多种排序算法,只有冒泡排序的名字起得这么形象。

提到冒泡你会想到什么,不管你想到了什么,反正我想到了烧水的场景,水中的气泡随着温度的上升越来越大,根据XXX原理可知,气泡在水里待不住了,然后它缓慢地从水底移动到水面,然后爆开,只要你烧过水,这个画面一定能够脑补出来。

其实冒泡排序和这个过程像极了,我们这次拿5个橘子来表演一下冒泡排序,5个大小不同的橘子排成一列,注意是一列,今天为了将冒泡排序不再用横排了,因为一列的橘子能分清上下,假设最下面的橘子是第1个,最上面的橘子是第5个,从下到上来模拟气泡从锅底冒出来的过程。

比如我们要从小到大排列,现在我们可以开始冒泡了,看看第1个橘子,再看看第2个,如果第1个比较大,那么把它和第2换下位置,也就是把大个的冒上去。

然后看看第2个橘子,在看看第3个橘子,如果第2个比较大,那么把第2个橘子和第3个橘子换一下位置,否则不交换,然后继续依次往后看,最后我们会看到第4个橘子和第5个橘子,同样的第4个比较大就交换,否则不动。

完成上述过程后,想象一下我们到底做了什么,我们实际上找到了最大的橘子,并且把它从下面的某个位置“冒泡”到了最上边,其实这就是网上常常所说的一趟排序,既然最大的橘子都到最上边了,所以它不需要再参与后面的排序过程。

下面来进行第二次冒泡,继续看看第1个橘子,再看看第2个,如果第1个比较大,那么把它和第2个换下位置,否则不动,依次进行,最后看看第3个橘子,再看看第4个,如果第3个比较大,那么把它和第4个换下位置,为什么是这次就比较到第4个呢,因为上一次冒泡第5个已经是最大的了,不需要再跟它比了,而这一次冒泡过后我们第4个橘子也变成第二大的了,不会再参与后面的排序。

有没有发现我们的范围在缩小,每次都能减少一个橘子的位置,那么想想一下一共5个橘子,我们需要几次冒泡才能排序完成?4次!注意是4次而不是5次,因为最后一次只剩下第一个橘子没有排序了,它肯定是最小的,不用再排了,这就是为什么冒泡排序的最外层的循环次数是N-1。

而我们每一次排序的最后一个都会减少1个,所以冒泡排序的第二层循环的结尾要减掉排序次数,依照这个思路很容易就能实现代码,并且也不会把边界弄错,搞出冒泡排序写成选择排序的笑话。

代码实现

/*
功能: 冒泡排序,实现数组元素从小到大排列
参数: array--表示待排序的数组,此处会退化成指针
        count--数组元素的个数
返回值:无
注意: 只用来表示思路,不考虑指针为空等特殊情况
*/
void bubble_sort(int array[], int count)
{
    for (int bubble_count = 0; bubble_count < count - 1; ++bubble_count)
    {
        for (int bubble_pos = 0; bubble_pos < count - 1 - bubble_count; ++bubble_pos)
        {
            if (array[bubble_pos] > array[bubble_pos + 1])
            {
                swap_data(&array[bubble_pos], &array[bubble_pos + 1]);  // 交换数据
            }
        }
    }
}

/*
功能: 交换两个变量
参数: element1--被交换的第一个元素的地址
        element2--被交换的第二个元素的地址
返回值:无
注意: 只用来表示思路,不考虑指针为空等特殊情况
*/
void swap_data(int* element1, int* element2)
{
    int middle_value = *element1;
    *element1 = *element2;
    *element2 = middle_value;
}

如果你跟着橘子的冒泡的思路走下来,相信你很容易就能理解这个算法实现,并且可以注意到边界条件的问题,代码就像上面这样,如果觉得我理解的有问题或者代码有错,也欢迎大家批评指正。

运行测试

冒泡排序–源码

如果你想运行测试一下,可以复制或者下载源代码,在本机运行测试一下,当然也可以选择在线编辑器,把源代码复制到网页中运行查看结果。

猜你喜欢

转载自blog.csdn.net/shihengzhen101/article/details/78001869
今日推荐