选择排序和快速排序算法原理和Python实现

来源:互联网 发布:茉莉苞茶软化宫颈 知乎 编辑:程序博客网 时间:2024/05/17 23:31

选择排序:这种排序算法思路比较简单,每一次都选出整个列表中的最小值或者最大值,直到结束。下面以最大值为例子。如果给你一个列表[1,5,6,2]。

第一步:通过比较选出最大值6,需要检查4个元素,计算3次,

第二步:通过比较选出剩余元素列表的最大的元素5,需要检查3个元素,计算2次

第三步:通过比较选出剩余元素列表的最大的元素2,需要检查2个元素,计算1次

第四步:剩余一个元素,结束

如果是列表元素有N个的情况下的分析类似上面:

第一步:通过比较选出最大值,需要检查N个元素,计算N-1次

第二步:通过比较选出剩余元素列表的最大的元素,需要检查N-1个元素

..............

直到结束

也就是每次选出最大值的过程都需要对比整个列表所有元素的值,才可以找出最大的值,一直到最后的一个列表只有一个元素结束,这样的计算复杂度是O(n*n)

例如:

def findSmallest(arr):smallest = arr[0]smallest_index = 0for i in range(1,len(arr)):if arr[i] < smallest:smallest = arr[i]smallest_index = ireturn smallest_indexdef selectionSort(arr):newArr = []for i in range(len(arr)):smallest_index = findSmallest(arr)newArr.append(arr.pop(smallest_index))return newArrA = [5, 6, 1, 2, 4]print selectionSort(A)
输出:

[1, 2, 4, 5, 6]

快速排序:快速排序是一种一般情况下比选择排序更加快的一种排序方法。它的思路就是每次都先从列表里面选出一个基准值,在把列表中的其他元素与它进行对比,比它大的放在右边组成一个新的列表,比它小的放在左边组成一个新的列表。基准值的选取最简单的就是选择列表的第一个元素,也可以随机选取,这就看你自己的意愿,选择第一个容易照成复杂度高一点,随机的话可能更可以得到平均的计算复杂度的时间,直到结束,结束的时候列表的元素也就是一个或者没有。比如:给一个列表为[3,5,6,1,4]

第一步:基准值选为3,小于它的列表为[1],大于它的列表为[5,6,4]

第二步:左边的结束了,只要处理右边的就可以,基准值为5,小于它的列表为[4],大于它的列表为[6],结束

第三步:把这些列表和基准值组合起来

结束

如果列表有N个元素,也是如此,可以利用递归实现这个程序,如果递归的深度太多,就会出错,内存不足,一般的编程语言中都会设置递归的最大深度,如果超过这个极限值,就报错,大家注意一下子就好了。

快速排序的计算复杂度是O(n*logn),这是一个平均的计算复杂度,也是最低的计算复杂度,最坏的情况就是选择排序一样的。如果你每次选择第一个元素是基准值,如果你的列表是一个有序的列表,比如[1,2,3,4],那就和选择排序一样.因为列表没有分成两半,所以是一样的。但是如果你每次选择中间的做基准值,那就每次都是一半,很快就可以结束,这是最好的情况,只有O(logn)。

下面解释一下平均计算复杂度:

在第一步选择基准值以后,完成对比划分的计算需要O(n),因为你要把这个元素和其他所有元素做对比

在第二步时,你已经分为两个列表和一个基准值,剩下列表的计算复杂度选好基准值,作比较,计算复杂度依旧是O(n),和第一步是一样的,都是要计算一个列表中基准值与所有其它值的对比情况。所以计算复杂度就是O(n*logn),这也是最低的计算复杂度。如果你每次都随机选择基准值,就可以达到这个计算复杂度,或者接近这个计算复杂度。因为随机选取不会受到列表本身排序的影响,列表是否有顺序我们是不知道的哈。这就可以解决每次基准值选取第一个元素因为列表本身已经排好序的影响了,所以推荐使用随机选取基准值。为了简单实现,下面的例子采用第一个元素为基准值

例如:

def quicksort(arr):if len(arr) < 2:return arrelse:pivot = arr[0]less = [i for i in arr[1:] if i <= pivot]greater = [i for i in arr[1:] if i > pivot]return quicksort(less) + [pivot] + quicksort(greater)A = [5, 6, 1, 2, 4]print quicksort(A)
输出:

[1, 2, 4, 5, 6]

参考:算法图解