排序方法python实现

冒泡

#标准版本
def bubble_sort(array):
    n = len(array)
    for i in range(n):  # i从0到n
        for j in range(1, n-i):  # 1开始,即j-1=0开始
            if array[j-1] > array[j]:
                array[j-1], array[j] = array[j], array[j-1]
    return array
#优化版本
def bubble_sort2(array):
    n = len(array)
    for i in range(n):
        flag = 1                    #标记
        for j in range(1,n-i):
            if  array[j-1] > array[j] :
                array[j-1],array[j] = array[j],array[j-1]
                flag = 0
        if flag :                   #标记为正,说明以上的都排好了,以后的迭代没意义了
            break
    return array
#优化版本2
def bubble_sort(array):
    n=len(array)
    k=n
    for i in range(n):
        flag=True
        for j in range(1,k):
            if array[j-1]>array[j]:
                array[j-1],array[j]=array[j],array[j-1]
                k=j                #记录最后交换的位置,后面的都排好了。
                flag=False
        if flag:
            break
    return array

选择排序

def selection_sort(array):       #每次把序列中的最小值换到最前面
    n = len(array)           #因为记录index交换少,所以性能略优于冒泡
    for i in range(n):
        minIndex = i
        for j in range(i+1, n):
            if array[j] < array[minIndex]:
                minIndex = j
        array[i], array[minIndex] = array[minIndex], array[i]
    return array

插入排序

def insert_sort(array):   #假设有概率序列初始状态就是局部有序,那么插入排序比冒泡和选择好。
    n=len(array)
    for i in range(1,n):
        if array[i-1]>array[i]:          #这句可以不要
            num=array[i]
            index=i
            for j in range(i-1,-1,-1):
                if array[j]>num:
                    array[j+1]=array[j]     #往后移动
                    index=j                 #腾出来的原来的位置就变成了可插入的位置被记录
                else:
                    break
            array[index]=num
    return array

希尔排序

def shell_sort(array):
    n=len(array)
    gap=round(n/2)     #设置gap
    while gap>0:
        for i in range(gap,n):   #这里相当于跨着步子的插入排序
            num=array[i]
            index=i
            while index>=gap and array[index-gap]>num:
                array[index]=array[index-gap]
                index=index-gap
            array[index]=num
        gap=round(gap/2)
    return array

归并排序

def merge_sort(array):  # 递归
    if len(array) <= 1: return array  # python每次都是新的数组,可以用数组长度小于等于1来判断
    num = len(array) // 2  # py27 3/2和3//2相同,python3 3//2才是地板除
    left = merge_sort(array[:num])
    right = merge_sort(array[num:])
    return merge(left, right)

def merge(left, right):  # 合并
    l,r = 0,0
    result = []
    while l < len(left) and r < len(right):
        if left[l] < right[r]:
            result.append(left[l])
            l = l + 1
        else:
            result.append(right[r])
            r += 1
    # 一边没有之后,加上所有的
    result += left[l:]
    result += right[r:]
    return result
'''--------------非递归----------------’‘'
def merge(seq, low, mid, high):
    left = seq[low: mid]
    right = seq[mid: high]
    k = 0 
    j = 0
    result = []
    while k < len(left) and j < len(right):
        if left[k] <= right[j]:
            result.append(left[k])
            k += 1
        else:
            result.append(right[j])
            j += 1
    result += left[k:]
    result += right[j:]
    seq[low: high] = result

def merge_sort(seq):
    i = 1 # i是步长
    while i < len(seq):
        low = 0
        while low < len(seq):
            mid = low + i #mid前后均为有序
            high = min(low+2*i,len(seq))
            if mid < high: 
                merge(seq, low, mid, high)
            low += 2*i
        i *= 2

快排

#递归形式
def quick_sort(array):
    """快速排序"""
    if len(array) >= 2:  # 递归入口及出口
        mid = array[len(array) // 2]  # 选取基准值,也可以选取第一个或最后一个元素
        left, right = [], []  # 定义基准值左右两侧的列表
        array.remove(mid)  # 从原始数组中移除基准值
        for num in array:
            if num >= mid:
                right.append(num)
            else:
                left.append(num)
        return quick_sort(left) + [mid] + quick_sort(right)
    else:
        return array
        
#非递归形式
def quick_sort(array):
    if len(array)<2: return array
    stack=[]
    stack.append(len(array)-1)
    stack.append(0)
    while stack:
        l=stack.pop()
        r=stack.pop()
        index=partition(array,l,r)
        if l<index-1:
            stack.append(index-1)
            stack.append(l)
        if r>index+1:
            stack.append(r)
            stack.append(index+1)
    return array

def partition(array,l,r):
    num=array[l]
    while l<r:
        while l<r and array[r]>=num:
            r-=1
        array[l]=array[r]
        while l<r and array[l]<=num:
            l+=1
        array[r]=array[l]
    array[l]=num
    return l

堆排序

def adjust_heap(heap,heapsize,father):
    left=2*father+1 #计算左儿子index
    right=left+1 #计算右儿子index
    large=father #最大值的index先默认为爸爸
    if left<heapsize and heap[large]<heap[left]:
        large=left
    if right<heapsize and heap[large]<heap[right]:
        large=right
    if large!=father:  #如果有最大值的index有调整,再交换
        heap[large],heap[father]=heap[father],heap[large]
        adjust_heap(heap,heapsize,large) #继续向下调整

def heap_sort(array):
    n=len(array)
    for father in range((n-2)//2,-1,-1):  #计算出最后一个父节点,然后一步一步往前遍历前面的父节点
        adjust_heap(array,n,father)

    for i in range(n-1,-1,-1):
        array[0],array[i]=array[i],array[0] #根结点(最大值)放最后一个
        adjust_heap(array,i,0)  #继续从根结点开始调整
    return array

排序算法复杂度分析

排序方法最好情况最坏情况平均情况空间复杂度稳定性
冒泡 O ( n ) O(n) O(n) O ( n 2 ) O(n^2) O(n2) O ( n 2 ) O(n^2) O(n2) O ( 1 ) O(1) O(1)稳定
选择排序 O ( n 2 ) O(n^2) O(n2) O ( n 2 ) O(n^2) O(n2) O ( n 2 ) O(n^2) O(n2) O ( 1 ) O(1) O(1)稳定
插入排序 O ( n ) O(n) O(n) O ( n 2 ) O(n^2) O(n2) O ( n 2 ) O(n^2) O(n2) O ( 1 ) O(1) O(1)稳定
希尔排序 O ( n 1.3 ) O(n^{1.3}) O(n1.3) O ( n 2 ) O(n^2) O(n2) O ( n l o g n ) − O ( n 2 ) O(nlogn)-O(n^2) O(nlogn)O(n2) O ( 1 ) O(1) O(1)不稳定
归并排序 O ( n l o g n ) O(nlogn) O(nlogn) O ( n l o g n ) O(nlogn) O(nlogn) O ( n l o g n ) O(nlogn) O(nlogn) O ( n ) O(n) O(n)稳定
堆排序 O ( n l o g n ) O(nlogn) O(nlogn) O ( n l o g n ) O(nlogn) O(nlogn) O ( n l o g n ) O(nlogn) O(nlogn) O ( 1 ) O(1) O(1)不稳定
快速排序 O ( n l o g n ) O(nlogn) O(nlogn) O ( n 2 ) O(n^2) O(n2) O ( n l o g n ) O(nlogn) O(nlogn) O ( l o g n ) − O ( n ) O(logn)-O(n) O(logn)O(n)不稳定
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值