排序算法

1 八大排序算法的时间复杂度和空间复杂度

排序算法 稳定性 平均时间复杂度 最差时间复杂度 空间复杂度 备注
堆排序 不稳定 O(nlogn) O(nlogn) O(1) n大时较好
快速排序 不稳定 O(nlogn) O(n^2) O(nlogn) n较大时好
希尔排序 不稳定 O(nlogn) O(n^s) O(1) s时所选的分组
选择排序 不稳定 O(n^2) O(n^2) O(1) n较小时较好
基数排序 稳定 O(logRB) O(logRB) O(n) B是真数(0--9),R是基数
冒泡排序 稳定 O(n^2) O(n^2) O(1) n小时较好
插入排序 稳定 O(n^2) O(n^2) O(1) 大部分已排序时较好
归并排序 稳定 O(nlogn) O(nlogn) O(1) n大时较好
  • 排序算法的稳定性
    假定再待排序的记录序列中,存在多个相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在序列中,A1=A2,且A1字A2之前,而在排序后的序列中,A1任在A2之前,则称这种排序算法是稳定的,否则成为不稳定的。

2 各排序算法的python实现

2.1 冒泡排序(稳定)

nums = [1,3,1,4,5,9,12,1,11,135,12,3,45,67,89,23]

def bubbleSort(arr):
    n = len(arr)
    for i in range(n):
        for j in range(0,n-i-1):
            if arr[j]>arr[j+1]:
                arr[j],arr[j+1] = arr[j+1],arr[j]
    return arr

bubbleSort(nums)

2.2 归并排序(稳定)

def merge(list_left,list_right):
    l,r = 0,0
    new_list = []
    while l < len(list_left) and r<len(list_right):
        if list_left[l] <= list_right[r]:
            new_list.append(list_left[l])
            l += 1
        else:
            new_list.append(list_right[r])
            r += 1
    new_list += list_left[l:]
    new_list += list_right[r:]
    return new_list

def mergeSort(arr):
    if len(arr) <= 1:
        return arr
    mid = len(arr)//2
    list_left = mergeSort(arr[:mid])
    list_right = mergeSort(arr[mid:])
    return merge(list_left,list_right)

arr = [12,33,15,11,1,1334,122234]
res = mergeSort(arr)
print(res)

2.3 插入排序(稳定)

def insertSort(arr):
    for i in range(len(arr)):
        preIndex = i - 1
        current = arr[i]
        while preIndex >=0 and arr[preIndex] > current:
            arr[preIndex+1]=arr[preIndex]
            preIndex -=1
        arr[preIndex+1] = current
    return arr
nums = [1,4,7,2,5,8,3,6,9,0]
insertSort(nums)

2.4 基数排序 (稳定)

def radixSort(arr):
    n = len(str(max(arr)))
    for k in range(n):
        bucket_list = [[] for i in range(10)]
        for i in arr:
            bucket_list[i//(10**k)%10].append(i)
        arr = [j for i in bucket_list for j in i]
    return arr

2.5 选择排序 (不稳定)

算法流程:
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
重复第二步,直到所有元素均排序完毕。

def selectionSort(arr):
    for i in range(len(arr)-1):
        minIndex = i # 记录最小数的索引
        for j in range(i+1,len(arr)):
            if arr[j]<arr[minIndex]:
                minIndex = j
        if i!= minIndex:
            arr[i],arr[minIndex] = arr[minIndex],arr[i]
    return arr     

nums = [1,4,7,2,5,8,3,6,9,0]
selectionSort(nums)

2.6 快速排序 (不稳定)

def quickSort(arr,i,j):
    if i >= j:
        return []
    pivot = arr[i] # 以第一个元素为基准
    low = i
    high = j
    while i < j:
        while i<j and arr[j]>=pivot:
            j -= 1
        arr[i] = arr[j]
        while i<j and arr[i] <= pivot:
            i += 1
        arr[j] = arr[i]
    arr[j] = pivot
    quickSort(arr,low,i-1)
    quickSort(arr,i+1,high)
    return arr

2.7 希尔排序

def shellSort(arr):
    n = len(arr)
    gap = int(n/2)
    while gap > 0:
        for i in range(gap,n):
            temp = arr[i]
            j = i
            while j >= gap and arr[j-gap] > temp:
                arr[j] = arr[j-gap]
                j -= gap
            arr[j] = temp
        gap = int(gap/2)
    return arr

2.8 堆排序

堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。堆排序可以说是一种利用堆的概念来排序的选择排序。

def heapify(arr, n, i): 
    largest = i  
    l = 2 * i + 1     # left = 2*i + 1 
    r = 2 * i + 2     # right = 2*i + 2 
  
    if l < n and arr[i] < arr[l]: 
        largest = l 
  
    if r < n and arr[largest] < arr[r]: 
        largest = r 
  
    if largest != i: 
        arr[i],arr[largest] = arr[largest],arr[i]  # 交换
        # 此时largest位置的数字(也就是最开始输入那个lis[i])处于待定状态,需要在它所有根部中确定其位置
        heapify(arr, n, largest) 
  
def heapSort(arr): 
    n = len(arr) 
  
    # Build a maxheap. 
    for i in range(n, -1, -1): 
        # 先把堆调整好小根堆的状态,在全堆中逐个调整每个数字的位置,调整的方法是在它所有根部中确定其位置
        heapify(arr, n, i) 
  
    # 一个个交换元素
    for i in range(n-1, 0, -1): 
        arr[i], arr[0] = arr[0], arr[i]   # 交换
        # 把新上来的0号安排到合适的位置上去,其中i指的是要调整的堆的范围
        heapify(arr, i, 0) 
posted @ 2021-09-06 11:25  爱吃西瓜的菜鸟  阅读(79)  评论(0编辑  收藏  举报