排序算法 python实现

算法详细过程参考:https://www.cnblogs.com/onepixel/articles/7674659.html
1.冒泡排序:每次交换相邻的两个元素,大的放到后面,这样一次遍历后最大元素会放到队尾。

def bubble(array):
    for i in range(len(array)):
        for j in range(1,len(array)-i):
            if array[j]< array[j-1]:
                array[j],array[j-1]=array[j-1],array[j]
    return array

2.选择排序:先选出最小的元素放在第一个位置,然后选出次小的放在第二个位置,依次类推。

def select(array):
    for i in range(len(array)):
        for j in range(i,len(array)):
            if(array[j]<array[i]):
                array[i],array[j]=array[j],array[i]
    return array

3.插入排序:像玩牌一样,将每个元素放到比它小的元素的后面,代码实现是记录下当前元素,如果前面的元素比当前元素大则将前面的元素后移。

def insert(array):
    for i in range(1,len(array)):
        j=i
        curr=array[i]
        while j>0 and array[j-1]>curr:
            array[j]=array[j-1]
            j-=1
        array[j]=curr
    return array

4.希尔排序:是插入排序的改进版,第一个突破 O(n2) O ( n 2 ) 的算法,先进行大步长的插入排序,再进行小步长的插入排序,最后是1步长的插入排序

def shell(array):
    k=1
    while k<len(array)/3:
        k=3*k+1
    while k:
        for i in range(k,len(array)):
            j=i
            curr=array[i]
            while j>0 and array[j-k]>curr:
                array[j]=array[j-k]
                j-=k
            array[j]=curr
        k=math.floor(k/3)
    return array

5.归并排序:分治思想,先将数组拆分,然后对拆分后的数组进行归并。也就是一直拆分到每个数组只有一个数,然后开始合并,合并的过程进行排序。

def merge_sort(array):
    def merge(left,right):
        i=0;j=0
        result=[]
        while i<len(left) and j<len(right):
            if left[i]<right[j]:
                result.append(left[i])
                i+=1
            else:
                result.append(right[j])
                j+=1
        while i<len(left):
            result.append(left[i])
            i+=1
        while j<len(right):
            result.append(right[j])
            j+=1
        return result
    if len(array)<=1:
        return array
    mid=len(array)//2
    left=merge_sort(array[:mid])
    right=merge_sort(array[mid:])
    return merge(left,right)

6.快速排序:是对冒泡排序的改进,是一种二分思想。每次选一个基准数,比它小的放在左边,比它大的放在右边,从左边选一个比基准大的,从右边选一个比基准小的,将两者交换。快速排序每一轮处理的是将这一轮的基准数放到正确的位置。

def quick(array):
    def sort(left,right,array):
        if left>right:
            return
        i=left
        j=right
        key=array[left]
        while i!=j:
            while array[j]>=key and i<j:
                j-=1
            while array[i]<=key and i<j:
                i+=1
            if i<j:
                a[i],a[j]=a[j],a[i]
        a[left],a[i]=a[i],a[left]
        sort(left,i-1,array)
        sort(i+1,right,array)
    sort(0,len(array)-1,array)
    return array

7.堆排序:首先构建堆,时间复杂度是 O(n) O ( n ) ,然后有点类似于选择排序,每次从堆里将最小的数并入到排好序的子数组后面进行堆调整,再将最小的取出来。

def MAX_Heapify(heap,HeapSize,root):#在堆中做结构调整使得父节点的值大于子节点

    left = 2*root + 1
    right = left + 1
    larger = root
    if left < HeapSize and heap[larger] < heap[left]:
        larger = left
    if right < HeapSize and heap[larger] < heap[right]:
        larger = right
    if larger != root:#如果做了堆调整则larger的值等于左节点或者右节点的,这个时候做对调值操作
        heap[larger],heap[root] = heap[root],heap[larger]
        MAX_Heapify(heap, HeapSize, larger)

def Build_MAX_Heap(heap):#构造一个堆,将堆中所有数据重新排序
    HeapSize = len(heap)#将堆的长度当独拿出来方便
    for i in range((HeapSize -2)//2,-1,-1):#从后往前出数
        MAX_Heapify(heap,HeapSize,i)

def HeapSort(heap):#将根节点取出与最后一位做对调,对前面len-1个节点继续进行对调整过程。
    Build_MAX_Heap(heap)
    for i in range(len(heap)-1,-1,-1):
        heap[0],heap[i] = heap[i],heap[0]
        MAX_Heapify(heap, i, 0)
    return heap

8.计数排序:线性排序,需要开辟额外的数组,只能排整数

def countingSort(alist,k):
    n=len(alist)
    b=[0 for i in range(n)]
    c=[0 for i in range(k+1)]
    #统计每个数出现的次数
    for i in alist:
        c[i]+=1
    #计算每个数应放在数组的哪个位置
    for i in range(1,len(c)):
        c[i]=c[i-1]+c[i]
    for i in alist:
        b[c[i]-1]=i
        c[i]-=1
    return b

9.桶排序:桶排序是计数排序的升级版,利用了函数的映射关系,当数据分布均匀时,可以将每一个数映射到桶内,桶内的数据进行排序,高效与否取决于映射关系。当数据分布不均匀时,建立最大值-最小值数目的桶。

def bucket(array):
    max_value=max(array)
    min_value=min(array)
    s=[0 for i in range(min_value,max_value+1)]
    #统计重复的数出现的个数
    for i in array:
        s[i-min_value]+=1
    current=min_value
    n=0
    for i in s:
        while i>0:
            array[n]=current
            i-=1
            n+=1
        #s里面有很多0,current的值是递增上去的
        current+=1
    return array

区间[0,1)均匀分布的桶排序

def sort(a):
    def insert(array):
        for i in range(1, len(array)):
            j = i
            curr = array[i]
            while j > 0 and array[j - 1] > curr:
                array[j] = array[j - 1]
                j -= 1
            array[j] = curr
    n=len(a)
    s=[[] for i in range(n)]
    for i in a:
        s[int(i/n)].append(i)
    for i in s:
        insert(i)
    return [i for j in s for i in j]

10.基数排序:基数排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序。最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。
Ptti7t.png
基于桶排序的基数排序

def RadixSort(list,d):
    for k in range(d):#d轮排序
        s=[[] for i in range(10)]#因为每一位数字都是0~9,故建立10个桶
        for i in list:
            s[i//(10**k)%10].append(i) #977/10=97(小数舍去),87/100=0
        list=[j for i in s for j in i]
    return list

附录:排序算法复杂度
PtA1Fx.png

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值