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) 
    
  • 相关阅读:
    GhostBSD 3.0RC3,基于GNOME的FreeBSD
    Nagios 3.4.3 发布,企业级监控系统
    Jolokia 1.0.6 发布, JMX远程访问方法
    微软希望开发人员不要使 WebKit 成为新版 IE6
    Kwort Linux 3.5 正式版发布
    EJDB 1.0.24 发布,嵌入式 JSON 数据库引擎
    Pale Moon 15.3 Firefox“苍月”优化版发布
    Galera Load Balancer 0.8.1 发布
    SmartSVN V7.5 正式发布
    PostgresQL建立索引如何避免写数据锁定
  • 原文地址:https://www.cnblogs.com/zhou-lin/p/15229859.html
Copyright © 2011-2022 走看看