前言


在辅导孩子学习算法的过程中,排序算法算是难点之一,一是因为排序算法的庞杂,二是有些排序算法实现起来相当抽象,不太容易理解,甚至从实例上来说是容易的,但从实例到抽象的过程,则是很不容易的,为此,在本文中,专门用python来实现交换排序中的两种排序方法,并结合逐步打印的过程来帮助孩子理解这些最基本算法的过程。


冒泡排序


对于很多读者来说,冒泡排序可能是最容易实现的排序算法之一,它的理论基础是数对的逆序问题,即将一个数列中所有相邻的逆序全都变成顺序,则这个数列即实现从小到大的排序。所谓逆序即是指类似于(5,3)这样较大的数在前,较小的数在后的数对。

[5,2,3,6,4,1]为例,其冒泡排序的过程及交换步骤如下图所示:


python 改变顺序 python数字调换顺序_python 改变顺序


从上图我们可以看出,每一步交换都是将原数列中的逆序变为顺序的过程,其程序代码如下:

def bubbleSort(lst=[5,2,3,6,4,1]):     counter = 0    j = len(lst)    while j>0:        for i in range(j-1):            if lst[i] > lst[i+1]:                            lst[i] , lst[i+1] = lst[i+1], lst[i]                  counter += 1                print(lst, "交换次数累计:", counter)        j -= 1    print("冒泡排序结果:{}共比较交换了{}次".format(lst, counter))


以上代码是容易读懂的,在检测到相邻数对是逆序时,交换并增加计数器值。从上述显示结果也很易得知最坏的情况是将整个逆序数列排列成顺序数列,此时需要交换的次数是1+2+3+...+(n-1)=n(n-1)/2


快速排序


相对于冒泡排序而言,快速排序用的是分类迭代思想,即先选中一个数做为关键数,然后将数列中凡是小于该数的均放于左侧,凡是大于该数的均放于右侧,然后分别对左右两侧数据重复以上方法,直到排序成功,下面还是以上述数列为例来说明: 首先选定一个关键数(比如第1个)后,分别从左右两端向中间逼近,此时将第1个数5从数列中取出,先从右端开始,凡每大于它一个,就向左移动1步,如果小于关键数,就需要将该较小的数移动至左端原关键数所在的位置,接着开始从左侧比较;从左侧比较时,凡每小于关键数一次,就向右移动1步,如果大于关键数,那就将该较大的数移动到右侧空处,将关键数存放于该较大数的地方,此时左指针指向关键数位置,右指针不变,循环即可。


python 改变顺序 python数字调换顺序_快速排序_02


该方法的代码如下:

def quick_sort(lst, left, right):    if left >= right:        return    low = left    high = right    key = lst[low]    while left < right:        while left < right and lst[right] > key:            right -= 1        lst[left] = lst[right]                 while left < right and lst[left] <= key:            left += 1                lst[right] = lst[left]                lst[left] = key                quick_sort(lst, low, left - 1)        quick_sort(lst, left + 1, high)


为了显示更清楚,我们为其增加上计数装置,代码如下:

counter = 0def quick_sort(lst, left, right):    global counter    if left >= right:        return    low = left    high = right    key = lst[low]    while left < right:        while left < right and lst[right] > key:            right -= 1        lst[left] = lst[right]         if lst[right] < key :             counter +=1                        print(lst, "排序次数累计:", counter)        while left < right and lst[left] <= key:            left += 1                lst[right] = lst[left]        if lst[left] > key:            counter += 2            print(lst, "排序次数累计:", counter)        lst[left] = key                quick_sort(lst, low, left - 1)        quick_sort(lst, left + 1, high)def quick_sort_ex(lst):    global counter    quick_sort(lst, 0, len(lst)-1)    print("快速排序后的结果为:{}, \n交换总次数为:{}".format(lst, counter))quick_sort_ex([5,2,3,6,4,1])

运行结果如下:

[1, 2, 3, 6, 4, 1] 排序次数累计:1[1, 2, 3, 6, 4, 6] 排序次数累计:3[1, 2, 3, 4, 4, 6] 排序次数累计:4快速排序后的结果为:[1, 2, 3, 4, 5, 6], 交换总次数为:4

小结


本文较详细介绍了交换排序的python算法实现,冒泡算法较为容易,快速排序相对复杂,需要仔细对照代码理解。