本节介绍了交换排序的基本思想。
冒泡排序的基本思想、运行过程、代码展现、时间复杂度、稳定性。
快速排序的的基本思想、运行过程、代码展现、时间复杂度、稳定性。
#冒泡排序:每次从后往前两两往前,把两两中小的往前交换
def BubbleSort(R):
for i in range(len(R)-1):
exchange=False#如果在一趟检验中,没有一次交换,那么说明已经排好了序,用exchange来标记
for j in range(len(R)-1,i,-1):#这个循环说明是倒着遍历的,i不断增大,说明有序序列不断减小
#一开始是检验整个表,下一趟就从左减少了一个长度,再下一趟又减少了一个长度……
if R[j]<R[j-1]:#按理讲小的应该在前面,如果小的在后面则出现异常,就要把这两个交换
R[j],R[j-1]=R[j-1],R[j]
exchange=True#只要进行了交换,就标记为True
if exchange==False:return
#交换排序中的快速排序
#快速排序:将小的放在基准的左边,大的放在基准的右边,最后留出位置把这个标准元素放在中间,然后对其左右子树进行循环(递归)
#这个将小的放在基准的左边,大的放在基准的右边是操作的关键,主要有两种主要的方法:
#Partition1:先从左边左边开头开始找到一个比基准元素大的标记出来,再从尾找到一个比基准小的元素标记出来(按理讲小的应该在前面,大的应该在后面),将这两个标记的位置进行交换,再
#分别指针后移前移进行剩余元素的遍历
#Partition2:将基准元素移出来,(以第一个元素为基准元素为例)空出这个位置,用指针low指向0号位(这个位置因为这个位置取出来作为标准位置了,所以一开始这个位置是空的)(并且在
#之后的递归过程中,low和high指针始终有一个标记空位置)high指向len(R)-1号位置。当low为空的时候,high往前遍历,找到一个比基准元素要小的,放入空的low里,然后将low后移一位
#(因为这个low位置已经操作过了,所以low后移一位便于遍历剩下的元素)。此时因为元素放在了前面,刚刚的high位置是空的,low从现在的位置往后遍历,找到一个比基准元素大的,放入high位置。
#不断重复,直到high=low,把基准元素填入。以基准元素为界,分为左右两段,依次进行递归。
def Partition1(R,s,t):#对顺序表的s到t位置进行排序
base=R[s]#将首元素设置为基准元素
i,j=s,t#i是前面的指针,用来标记从前面找到的比基准大的元素,j是后面的指针,用来标记从后面找到的比基准小的元素
while i<j:#两个指针还没有碰到的时候就循环
while i<j and R[j]>=base:#从后面向前面找一个小元素
j-=1
while i<j and R[i]<=base:#从前面向后面找一个大元素
i+=1
if i<j:#两个指针还么有碰到,将上面找到的大小元素交换
R[i],R[j]=R[j],R[i]
R[s],R[i]=R[i],R[s]#两个指针碰到了说明最后剩了一个空位置,把基准元素放进去
#重新进入大的while循环
return i#返回最后基准元素放入的位置,便于递归
def Partition1_1(R,s,t):#我个人觉得这个优化就是调整了比较的次序,个人觉得没有必要,给大家放在这里供大家参考
base=R[s]
i,j=s,t+1
while True:
i+=1
while R[i]<base:
if i==t:break
i+=1
j-=1
while base<R[j]:
if j==s:break
j-=1
if i>=j:break
R[i],R[j]=R[j],R[i]
R[s],R[i]=R[j],R[s]
return j
#Partition2:将基准元素移出来,(以第一个元素为基准元素为例)空出这个位置,用指针low指向0号位(这个位置因为这个位置取出来作为标准位置了,所以一开始这个位置是空的)(并且在
#之后的递归过程中,low和high指针始终有一个标记空位置)high指向len(R)-1号位置。当low为空的时候,high往前遍历,找到一个比基准元素要小的,放入空的low里,然后将low后移一位
#(因为这个low位置已经操作过了,所以low后移一位便于遍历剩下的元素)。此时因为元素放在了前面,刚刚的high位置是空的,low从现在的位置往后遍历,找到一个比基准元素大的,放入high位置。
#不断重复,直到high=low,把基准元素填入。以基准元素为界,分为左右两段,依次进行递归。
def Partition2(R,s,t):#对顺序表的s到t位置进行排序
i,j=s,t#i是前面的指针,用来标记从前面找到的比基准大的元素,j是后面的指针,用来标记从后面找到的比基准小的元素
base=R[s]#将首元素设置为基准元素
while i!=j:#因为这个i和j的指针都是一个一个移动的,所以当i和j没有碰到一起就继续循环
#low指向空的话,从后往前移动high,找一个比基准小的数填到low,low后移一位
#high指向空的话,从前往后移动low,找一个比基准大的数填到high,high前移一位
#这两操作始终成组成组出现,所以两个操作并称一个大组进行while循环
while j>i and R[j]>=base:#从后往前找一个大于基准元素的元素
j-=1
if j>i:
R[i]=R[j]#填到前面的空位置
i+=1
while i<j and R[i]<=base:#从前往后找一个大于基准元素的元素
i+=1
if i<j:
R[j]=R[i]#填到后面的空位置
j-=1
R[i]=base#两个指针碰到了说明最后剩了一个空位置,把基准元素放进去
return i#返回最后基准元素放入的位置,便于递归
def QuickSort(R):#进行递归操作
QuickSort1(R,0,len(R)-1)
def QuickSort1(R,s,t):#对左右子树不断递归
if s<t:
i=Partition2(R,s,t)
QuickSort1(R,s,i-1)
QuickSort1(R,i+1,t)