【算法导论】笔记-第七章 线性时间排序

第7章 线性时间排序

  • 比较排序:在排序的结果中,各元素的次序依赖于它们之间的比较

7.1 排序算法的下界

  • 决策树模型:比较排序可以抽象为一颗决策树
  • 决策树:决策树是一颗完全二叉树,可以表示在给定输入规模情况下,某一特定排序算法对所有元素的比较操作。
  • 读决策树:结点(a:b)表示判断a与b的大小关系。结点后面的"<“和”>"表示a与b的确定关系。根结点表示满足之前所有决策的结果。
  • 最坏情况下的下界:在决策树中,从根结点到任意一个可达叶结点之间最长简单路径的长度,表示对应的排序算法中最坏情况的比较次数。即比较排序算法中的最坏情况比较次数就是决策树的高度。
  • 定理:在最坏情况下,任何比较排序算法都需要做 Ω ( n lg ⁡ n ) \Omega(n\lg n) Ω(nlgn)次比较。

7.2 计数排序

  • 思想:对每个输入元素x,确定小于x的元素个数。该数即为元素x在输出数组中的位置。

  • 伪代码:COUNTING-SORT(A, B, k)

    \\A为原数组,B用来存放排序输出,k为A中元素最大值
    let C[0..k] be a new array \\提供临时存储空间
    
    for i = 0 to k \\初始化C数组
        C[i] = 0
    
    for j = 1 to A.length \\让C数组中元素位置代表A中元素大小
        C[A[j]] = C[A[j]] + 1
    
    for i = 1 to k
        C[i] = C[i] + C[i-1]\\统计小于元素C[i]的元素数量
    
    for j = A.length downto 1
        B[C[A[j]]]=A[j]
        C[A[j]] = C[A[j]]-1
    
  • python代码:

    def counting_sort(old_array, new_array, k):
        temp_array = k * [0]
        for j in range(0, len(old_array)):
            temp_array[old_array[j]] = temp_array[old_array[j]] + 1
        for i in range(1, k):
            temp_array[i] = temp_array[i] + temp_array[i-1]
        for j in range(len(old_array)-1, 0, -1):
            new_array[temp_array[old_array[j]]] = old_array[j]
            temp_array[old_array[j]] = temp_array[old_array[j]] - 1
        return new_array
            
    A = [16, 4, 10, 14, 7, 9, 3, 2, 8, 1]
    B = len(A) * [0]
    k = 30
    
    print(counting_sort(A, B, k))
    

7.3 基数排序

  • 思想:将数组中的所有数按位进行分类,由于每一位数的大小都在0~9之间,因此创建下标为0-9的十个数组,根据需要对数进行存储。

7.4 桶排序

  • 思想:假设输入数据服从均匀分布(由随机过程产生)。将待排序的数据分到几个有序的里,每个桶的数据单独排序,桶内排完序后,再按顺序依次取出,组成有序序列。

  • 伪代码:BUCKET-SORT(A)

    n = A.length
    let B[0..n-1] be a new array
    for i = 0 to n-1
        make B[i] an empty list
    for i = 1 to n
        insert A[i] into list B[(nA[i])的向下取整]
    for i = 0 to n-1
        sort list B[i] with insertion sort
    concatenate the lists B[0],B[1],···,B[n-1] together in order
    
  • python代码:

    import math
    import numpy as np
    
    ##### 插入排序
    def insert_sort(mylist):
        length = len(mylist) #获取列表长度
        for i in range(1,length):
             j = i - 1 #设置当前值前一个元素的标识    
             if(mylist[i] < mylist[j]): #如果当前值小于前一个元素,则将当前值作为一个临时变量存储,将前一个元素后移一位
                 temp = mylist[i]
                 mylist[i] = mylist[j]
                 j = j-1 #继续往前寻找,如果有比临时变量大的数字,则后移一位,直到找到比临时变量小的元素或者达到列表第一个元素
                 while j>=0 and mylist[j] > temp:
                     mylist[j+1] = mylist[j]
                     j = j-1
                 mylist[j+1] = temp #将临时变量赋值给合适位置
        return mylist
    
    ##### 桶排序
    def bucket_sort(old_list):
        n = len(old_list)
        new_list = n * []
        for i in range(1, n):
            p = math.floor(n*old_list[i])
            new_list.insert(p, old_list[i])
            
        for i in range(0, n-1):
            insert_sort(new_list)
            
        return new_list
    
    A = np.random.random(10)
    print(bucket_sort(A))
    
  • 运行时间: θ ( n ) \theta(n) θ(n)

你可能感兴趣的:(算法导论,算法,数据结构,python,排序算法)