常见排序算法比较
1.冒泡排序
def bubble_sort(alist):
for j in range(len(alist)-1,0,-1):
## j是从第一个数到最后一个数需要移动的次数
for i in range(j):
if alist[i]>alist[i+1]:
alist[i],alist[i+1]=alist[i+1],alist[i]
return alist
li=[54,26,93,17,77,31,44,55,20]
bubble_sort(li)
print(li)
2.选择排序
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]
return alist
alist=[54,26,93,17,77,31,44,55,20]
selection_sort(alist)
print(alist)
3.插入排序
def insert_sort(alist):
## 从第二个位置即下标为1的元素开始向前插入
for i in range(1,len(alist)):
## 从第i个元素开始向前比较,如果小于前一个元素则交换位置
for j in range(i,0,-1):
if alist[j]<alist[j-1]:
alist[j-1],alist[j]=alist[j],alist[j-1]
return alist
li=[54,26,93,17,77,31,44,55,20]
insert_sort(li)
print(li)
4.快速排序
def quick_sort(alist,start,end):
## 设置递归退出条件
if start>=end:
return
## 设定起始元素为基准元素
mid=alist[start]
## left为序列左边的由左向右移动的游标
left=start
## right为序列右边的由右向左移动的游标
right=end
while left<right:
## 如果left与right没有重合,right指向的元素不比基准元素小,则right向左移动
while left<right and alist[right]>=mid:
right-=1
## 将right指向的元素放到left位置上
alist[left]=alist[right]
## 如果left与right没有重合,left指向的元素不比基准元素大,则left向右移动
while left<right and alist[left]<=mid:
left+=1
## 将left指向的元素放到right位置上
alist[right]=alist[left]
## 退出循环后,left与right重合,此时所指位置为基准元素的正确位置
## 将基准元素放到该位置
alist[left]=mid
## 对基准元素左边的子序列进行快速排序
quick_sort(alist,start,left-1)
## 对基准元素右边的子序列进行快速排序
quick_sort(alist,left+1,end)
return alist
li=[54,26,93,17,77,31,44,55,20]
quick_sort(li,0,len(li)-1)
print(li)
5.希尔排序
def shell_sort(alist):
n=len(alist)
## 起始步长
gap=n//2
while gap>0:
## 按步长进行插入排序
for i in range(gap,n):
j=i
while j>=gap and alist[j-gap]>alist[j]:
alist[j-gap],alist[j]=alist[j],alist[j-gap]
j-=gap
## 得到新的步长
gap=gap//2
return alist
li=[54,26,93,17,77,31,44,55,20]
shell_sort(li)
print(li)
6.归并排序
def merge_sort(alist):
if len(alist)<=1:
return alist
## 二分分解
num=len(alist)//2
left=merge_sort(alist[:num])
right=merge_sort(alist[num:])
## 合并
return merge(left,right)
## 合并操作,将两个有序数组left和right合并成一个大的有序数组
def merge(left,right):
## left和right的下标指针
l,r=0,0
res=[]
while l<len(left) and r<len(right):
if left[l]<right[r]:
res.append(left[l])
l+=1
else:
res.append(right[r])
r+=1
res+=left[l:]
res+=right[r:]
return res
li=[54,26,93,17,77,31,44,55,20]
sorted_li=merge_sort(li)
print(sorted_li)
7.堆排序
def heap_sort(alist):
## 调整堆
## 对非叶子节点i 检查是否满足父母优势条件
def adjust_heap(alist,i,size):
## i的左右孩子节点
lchild=2*i+1
rchild=2*i+2
## 在节点i及左右孩子中找到最大元素的索引
largest=i
if lchild<size and alist[lchild]>alist[largest]:
largest=lchild
if rchild<size and alist[rchild]>alist[largest]:
largest=rchild
## 如果最大元素的索引不是i 则把大的节点交换到上面
if largest!=i:
alist[largest],alist[i]=alist[i],alist[largest]
## 交换之后i到了largest的位置,继续检查它的左右孩子节点来调整堆
adjust_heap(alist,largest,size)
## 建立最大堆
def build_heap(alist,size):
## 从倒数第一个非叶子节点开始建立最大堆
for i in range(len(alist)//2)[::-1]:
## 对所有非叶子节点进行堆的调整
adjust_heap(alist,i,size)
## 堆排序
size=len(alist)
build_heap(alist,size)
## 从最后一个节点向前
for i in range(size)[::-1]:
## 交换根节点与最后一个节点
alist[0],alist[i]=alist[i],alist[0]
## 对新的根节点进行堆的调整,此时删除了最大元素,因此数组的size不包括已经排序好的数
adjust_heap(alist,0,i)
return alist
li=[54,26,93,17,77,31,44,55,20]
heap_sort(li)
print(li)
参考:
https://www.cnblogs.com/fwl8888/p/9315730.html
https://cloud.tencent.com/developer/article/1108770(堆排序)