#python数据结构与算法分析#
今天快速过一遍算法中重要的排序部分
从最基础的两个排序开始:1.冒泡排序(bubble sort)
2.选择排序(selection sort)
首先是冒泡排序
冒泡排序多次遍历列表,它比较相邻的元素,将不合顺序的交换。在每一轮遍历都将下一个最大值放在正确的位置。 事实上就是,每个元素通过”冒泡“找到自己的位置。
来看一下实际图:
让我们看看,它进行冒泡排序的时候,下标【4】的76与下标【3】的18进行交换,而到76与99表比较的时候,却不发生改变,但遍历还没有结束,最大值由76变为99,没有遇到其它更大的数,99一直遍历到正确的位置。这一过程会持续的遍历结束
我们来看看代码:
def bubblesort(alist):
for passnum in range(len(alist)-1,0,-1):
for j in range(passnum):
if alist[j] > alist[j+1]:
temp = alist[j]#暂存alist[j]的值
alist[j] = alist[j+1]
alist[j+1] = temp
return alist
"""
#1 先第一步遍历,并赋值给passnum
#2 设置变量j 从小到大逐个比较大小
第一步遍历得值:5,4,3,2,1 先是5被调用,然后依次类推
第二步,通过迭代来比较不同下标之间的值
#3-#5进行交换 先用一个临时变量来装alist[j]的值
后面才好使用
其实也可以进行同时赋值
alist[j],alist[j+1] = alist[j+1],alist[j]
这就完成整个交换
最后用return返回排好序的列表
"""
第二遍的遍历开始时,最大值已经在正确的位置上了。那么还剩下n-1个元素需要排列,还要比较n-2对。既然每一轮都将下一个最大的元素放到正确的位置上,那么需要遍历的轮数就是n-1.
完成n-1轮后,最小的元素必然在正确的位置上,就不需要处理了
注意:如果没有临时存储位置,其中一个值就会被覆盖。
冒泡排序是简单的排序,也通常被认为是效率最低的排序算法,要在确定最终的位置前必须交换元素。那么我们进行一定的修改,让它能够判断出有序列表并终止排序过程。
def shortbubblesort(alist):
exchange = True
passnum = len(alist)-1
while passnum > 0 and exchange:
exchange = False
for i in range(passnum):
if alist[i] > alist[i+1]:
exchange = True
alist[i],alist[i+1] = alist[i+1],alist[i]
passnum = passnum - 1
return alist
这里不过有少处进行改变,就是----如果在一轮遍历中没有发生元素交换,就可以确定列表已经有序了。因为没有元素进行交换,则exchange 在while处被赋值为False ,那没有进行元素交换
则exchange仍然为False ,即该列表已经有序。这个叫短冒泡(short bubblesort)
现在来到-----选择排序
选择排序是在冒泡排序上的基础上进行了改进,每一次的遍历只用进行一次的元素交换即可。
那么我们想实现这一点,那么选择排序在每一次遍历时寻找最大值,并在遍历完之后将它放到正确位置上。与冒泡排序相似的时,每一次的遍历后,最大元素在正确位置,依次类推,若给n个元素排序,则需要遍历n-1轮,因为最后一个元素要到n-1轮遍历后才可以就位。
事不宜迟,我们来看看代码。
def selectionsort(alist):
for fillslot in range(len(alist)-1,0,-1):
positionOfMax = 0
for location in range(1,fillslot+1):
if alist[location] > alist[positionOfMax]:
positionOfMax = location
#这里是不断比较两者值,把值大的位置交换,并保留下来
temp = alist[fillslot]
alist[fillslot] = alist[positionOfMax]
alist[positionOfMax] = temp
return alist
"""
fillslot 是从5开始逐渐减小到1
当找到最大值位置时,便可以将进行交换
然后进行下一轮的遍历,n-1的遍历再进行交换
"""
选择排序与冒泡排序算法比较次数相同,所以时间复杂度为O(n**2).但是,由于减少了交换次数,因此选择排序算法通常更快。