zoukankan      html  css  js  c++  java
  • 排序算法

    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) 
    
  • 相关阅读:
    (原创)C++ 同步队列
    (原创)用C++11的std::async代替线程的创建
    C语言宏应用-------#define STR(X) #X
    c++中数据表如何转成业务实体--map和结构体的相互转换
    线程池的陷阱
    java中map和对象互转工具类的实现示例
    3.python元类编程
    人生苦短,我用python(目录)
    11.多线程、多进程和线程池编程
    10.python3实用编程技巧进阶(五)
  • 原文地址:https://www.cnblogs.com/zhou-lin/p/15229859.html
Copyright © 2011-2022 走看看