常见排序算法总结与实现(python)

#常见排序算法总结与python实现

文章目录


这里写图片描述
说明:
稳定性定义:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,ri=rj,且ri在rj之前,而在排序后的序列中,ri仍在rj之前,则称这种排序算法是稳定的;否则称为不稳定的。
##插入排序:
插入排序具体算法描述如下:

  1. 从第一个元素开始,该元素可以认为已经被排序
  2. 取出下一个元素,在已经排序的元素序列中从后向前扫描
  3. 如果该元素(已排序)大于新元素,将该元素移到下一位置
  4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
  5. 将新元素插入到该位置后
  6. 重复步骤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())

##冒泡排序:
冒泡排序算法的运作如下:

  1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
  3. 针对所有的元素重复以上的步骤,除了最后一个。
  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
    ###代码实现
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)策略来把一个序列分为两个子序列。
步骤为:

  1. 从数列中挑出一个元素,称为"基准"(pivot),
  2. 重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(相同的数可以到任何一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
  3. 递归地(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)

##归并排序
算法思路:

  1. 把 n 个记录看成 n 个长度为 l 的有序子表
  2. 进行两两归并使记录关键字有序,得到 n/2 个长度为 2 的有序子表
  3. 重复第 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)

参考资料:
维基百科、《算法导论》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值