算法漫游指北(第七篇):冒泡排序冒泡排序算法描述动图演示代码实现过程分析时间复杂度和选择排序算法描述动图演示代码实现过程分析时间复杂度

Posted nicholas0707

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法漫游指北(第七篇):冒泡排序冒泡排序算法描述动图演示代码实现过程分析时间复杂度和选择排序算法描述动图演示代码实现过程分析时间复杂度相关的知识,希望对你有一定的参考价值。

一、冒泡排序

冒泡排序是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。

算法描述

  • 比较相邻的元素。如果第一个比第二个大,就交换它们两个;

  • 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;

  • 针对所有的元素重复以上的步骤,除了最后一个;

  • 重复步骤1~3,直到排序完成。

 

冒泡排序动图演示

技术图片

 技术图片

冒泡排序代码实现

def bubble_sort(arrlist):
?
    # 如果列表长度是0,1,则不用排序
    if len(arrlist) < 2:
        return 
?
?
    n = len(arrlist)
    for j in range(n-1,0,-1):
        for i in range(j):
            # 从列表的下标为0开始比较,比较0-1,1-2,。。。一直比较到i-i+1
            # 如果前面的数比后面的数大,就把前面的数换到后面来
            if arrlist[i] > arrlist[i+1]:
                arrlist[i],arrlist[i+1] = arrlist[i+1],arrlist[i]
    
?
if __name__ == "__main__":
    li = [54, 26, 93, 17, 77, 31, 44, 55, 20]
    print(li)
    bubble_sort(li)
    print(li)

  

 

冒泡排序过程分析

li = [54, 26, 93, 17, 77, 31, 44, 55, 20]

1、第一遍冒泡

for i in range(0, n-1):
    # 指针从头走到尾
    if alist[i] > alist[i+1]:
    alist[i],alist[i+1] = alist[i+1], alist[i]

  

针对列表元素的0和1,比较54比26大,换位置

[ 26, 54,93, 17, 77, 31, 44, 55, 20]

针对列表元素的1和2比较,54和93比较,小,不用动

[ 26, 54,93, 17, 77, 31, 44, 55, 20]

针对列表元素的2和3比较,93和17比较,大,换位置

[ 26, 54,17, 93, 77, 31, 44, 55, 20]

......

以此类推

最后把93移动到了最后的位置

[54, 26, 17, 77, 31, 44, 55, 20,93]

这样93的位置就可以确定了

 

 

 

2、第二遍冒泡

因为最后的93位置确定了,那么第二遍就可以直接对剩下的元素进行排序

即 [54, 26, 17, 77, 31, 44, 55, 20],这样第二遍排序就少了一个元素

与第一遍排序一样,还是从下标为0的元素开始两两比较,移动元素,

最后的结果就是将整个列表第二大的元素移动到最后

确定了列表倒数第二个元素的位置。

 

3、第三篇冒泡、第四篇冒泡...

依次类推

最后要循环的是len(li)-1次

 

得到代码是

def bubble_sort(alist):
    """冒泡排序"""
    n = len(alist)
    for j in range(n-1):
        count = 0
        for i in range(0, n-1-j):
            # 指针从头走到尾
            if alist[i] > alist[i+1]:
                alist[i],alist[i+1] = alist[i+1], alist[i]

  


         

与上面代码实现有一点不同,这里外层for循环用的是0到n-1,代码实现用的是相反的,原理都是一样的。

 

冒泡排序时间复杂度

  • 最优时间复杂度:O(n) (表示遍历一次发现没有任何可以交换的元素,排序结束。)

  • 最坏时间复杂度:O(n2)

  • 稳定性:稳定

 

二、选择排序

选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理如下。首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

 

选择排序动作有点和冒泡排序是相逆的,选择排序是将最小的放在元素最前面,冒泡排序是将最大的放在最后面。

 

选择排序的主要优点与数据移动有关。如果某个元素位于正确的最终位置上,则它不会被移动。选择排序每次交换一对元素,它们当中至少有一个将被移到其最终位置上,因此对n个元素的表进行排序总共进行至多n-1次交换。在所有的完全依靠交换去移动元素的排序方法中,选择排序属于非常好的一种。

 

算法描述

n个记录的直接选择排序可经过n-1趟直接选择排序得到有序结果。具体算法描述如下:

  • 设第一个元素为比较元素,依次和后面的元素比较,比较完所有元素找到最小的元素,将它和第一个元素互换

  • 重复上述操作,我们找出第二小的元素和第二个位置的元素互换,以此类推找出剩余最小元素将它换到前面,即完成排序

 

选择排序动图演示

技术图片

 技术图片

红色表示当前最小值,黄色表示已排序序列,蓝色表示当前位置。

选择排序代码实现

 

def selection_sort(alist):
    n = len(alist)
    # 需要进行n-1次选择操作
    for i in range(n-1):
        # 记录最小位置
        min_index = i
        # 从i+1位置到末尾选择出最小数据
        for j in range(i+1, n):
            if alist[j] < alist[min_index]:
                min_index = j
        # 如果选择出的数据不在左边的位置,进行交换
        if min_index != i:
            alist[i], alist[min_index] = alist[min_index], alist[i]
?

  

 

选择排序过程分析

arrli=[6,5,4,3,2,1]

  

 

1、第一遍选择排序

选择min_index = 0,假设第0个元素是最小的,将其他的1-n个元素与第0个元素进行比较

即执行for循环

for i inrange(0+1,6):
    if alist[i] < alist[min_index]:
        min_index = i

  

即将第一个元素6 分别与另外的5,4,3,2,1进行比较,如果另外的元素比6小,则min_index值为该元素的下标。这里通过for循环之后得到min_index=5。即第五个元素比第0个元素小。

将第五个元素和第0个元素进行互换。

alist[i], alist[min_index] = alist[min_index], alist[i]

  

第一次选择排序结果

[1, 5, 4, 3, 2, 6]

 

2、第二遍选择排序

确定了第0个元素的位置,将第0个元素剔除,对

 [5, 4, 3, 2, 6]

进行选择排序

与上面类似

开始假定第1个元素5为最小,与其他的进行比较,得到min_index = 4

将第4个元素和第1个元素进行互换。

[1, 2, 4, 3, 5, 6]

 

3、继续for循环,与上面类似,直到循环到n-2

 

选择排序时间复杂度

  • 最优时间复杂度:O(n^2)

  • 最坏时间复杂度:O(n^2)

  • 稳定性:不稳定(考虑升序每次选择最大的情况)

 

 

参考资料

[1]https://www.cnblogs.com/onepixel/p/7674659.html

以上是关于算法漫游指北(第七篇):冒泡排序冒泡排序算法描述动图演示代码实现过程分析时间复杂度和选择排序算法描述动图演示代码实现过程分析时间复杂度的主要内容,如果未能解决你的问题,请参考以下文章

算法漫游指北(第九篇):快速排序算法描述动图演示代码实现过程分析时间复杂度

算法漫游指北(第八篇)插入排序算法描述动图演示代码实现过程分析时间复杂度和希尔排序算法描述动图实现代码实现过程分析时间复杂度

算法漫游指北(第八篇)插入排序算法描述动图演示代码实现过程分析时间复杂度和希尔排序算法描述动图实现代码实现过程分析时间复杂度

算法漫游指北(第十一篇):归并排序算法描述动图演示代码实现过程分析复杂度

[ 数据结构 -- 手撕排序算法第七篇 ] 堆及其堆排序

D3学习指北--第三章应用,冒泡排序的可视化