#常见排序算法总结与python实现
文章目录
说明:
稳定性定义:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,ri=rj,且ri在rj之前,而在排序后的序列中,ri仍在rj之前,则称这种排序算法是稳定的;否则称为不稳定的。
##插入排序:
插入排序具体算法描述如下:
- 从第一个元素开始,该元素可以认为已经被排序
- 取出下一个元素,在已经排序的元素序列中从后向前扫描
- 如果该元素(已排序)大于新元素,将该元素移到下一位置
- 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
- 将新元素插入到该位置后
- 重复步骤2~5
###代码实现
def Insertation_sort(or_array):
if not or_array:
return None
if len(or_array) == 1:
return or_array
for i in range(0,len(or_array)):
key = or_array[i]
j=i-1
while (j>=0 and key < or_array[j]) :
or_array[j+1]=or_array[j]
j -= 1
or_array[j+1]=key
return or_array
#instance
A=[5,2,4,6,1,3]
A_sorted=Insertation_sort(A.copy())
##冒泡排序:
冒泡排序算法的运作如下:
- 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
###代码实现
def Bubble_sort(array):
for i in range(0,len(array)-1):
for j in range(0,len(array)-1-i):
if array[j]>array[j+1]:
array[j],array[j+1] = array[j+1],array[j]
return array
#instance
A=[5,2,6,1,3,4,5]
A_sorted=Bubble_sort(A.copy())
##快速排序
快速排序使用分治法(Divide and conquer)策略来把一个序列分为两个子序列。
步骤为:
- 从数列中挑出一个元素,称为"基准"(pivot),
- 重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(相同的数可以到任何一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
- 递归地(recursively)把小于基准值元素的子数列和大于基准值元素的子数列排序。
递归到最底部时,数列的大小是零或一,也就是已经排序好了。这个算法一定会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。
###代码实现
def Quick_sort(array,p,r):
if p<r :
q = Partition(array,p,r)
Quick_sort(array,p,q-1)
Quick_sort(array,q+1,r)
def Partition(array,p,r):
key = array[r]
q=p-1
for i in range(p,r):
if array[i]<=key:
q +=1
array[i],array[q]=array[q],array[i]
array[q+1],array[r]=array[r],array[q+1]
return q+1
#instance
array=[8,5,5,4,1,2,4,7,6,3,7,9]
Quick_sort(array,0,len(array)-1)
##堆排序
在堆的数据结构中,堆中的最大值总是位于根节点。堆中定义以下几种操作:
• 最大堆调整(Max_Heapify):将堆的末端子节点作调整,使得子节点永远小于父节点
• 创建最大堆(Build_Max_Heap):将堆所有数据重新排序
• 堆排序(HeapSort):移除位在第一个数据的根节点,并做最大堆调整的递归运算
###代码实现
class Heap_array:
def __init__(self,array,size):
self.array=array
self.size=size
def Max_Heapify(Heap,i):
left = 2*i+1
right= 2*i+2
largest = i
if left<Heap.size and Heap.array[largest]<Heap.array[left]:
largest = left
if right<Heap.size and Heap.array[largest]<Heap.array[right]:
largest = right
if largest !=i :
Heap.array[largest],Heap.array[i]=Heap.array[i],Heap.array[largest]
Max_Heapify(Heap,largest)
def Build_max_Heap(Heap):
for i in range(int(floor(Heap.size/2))-1,-1,-1):
Max_Heapify(Heap,i)
def Heap_sort(array):
if not array:
return None
Heap=Heap_array(array,len(array))
Build_max_Heap(Heap)
for i in range(len(array)-1,0,-1):
Heap.array[0],Heap.array[i]=Heap.array[i],Heap.array[0]
Heap.size -= 1
Max_Heapify(Heap,0)
return Heap.array
#instance
array=[1,4,3,44,55,3,2,6,7,55,4,7]
sorted_array=Heap_sort(array)
##归并排序
算法思路:
- 把 n 个记录看成 n 个长度为 l 的有序子表
- 进行两两归并使记录关键字有序,得到 n/2 个长度为 2 的有序子表
- 重复第 2 步直到所有记录归并成一个长度为 n 的有序表为止。
###代码实现
def Merge(A,p,q,r):
#we assume that : A[p,q] and A[q+1,r] are already sorted
L=[0]*(q-p+2)
R=[0]*(r-q+1)
L[-1]=+inf
R[-1]=+inf
L[0:-1]=A[p:q+1]
R[0:-1]=A[q+1:r+1]
i=0
j=0
for k in range(p,r+1):
if L[i]<R[j]:
A[k]=L[i]
i += 1
else:
A[k]=R[j]
j += 1
def Merge_sort(A,p,r):
if p<r:
q=int(floor((p+r)/2))
Merge_sort(A,p,q)
Merge_sort(A,q+1,r)
Merge(A,p,q,r)
return A
#instance
array=[2,1,7,5,3,7,4,5,6,7,5]
sorted_array=Merge_sort(array,0,len(array)-1)
参考资料:
维基百科、《算法导论》