排序

  1. 插入排序  insertion-sort

插入排序原理:像排序扑克牌,开始时左手为空并且桌面上牌面向下。然后,每次从桌子上拿走一张并将它插入到正确的位置。为了找到每一张牌的正确位置,我们从右到左将它与手中的牌进行比较。

时间复杂度:O(n2)

def insertion-sort(A):   #A为数组
    for j in range(2, length(A)):
        key = A[j]
        i = j-1          #将A[i]插入序列A[1,2,3,...,j]
        while i > 0 && A[i] > key:
            A[i+1] = A[i]
            i = i - 1
        A[i+1] = key



2. 归并排序算法 merge

归并排序算法原理:假设桌上有两堆牌面朝上的牌,每堆都已排序,最小的牌在顶上。基本步骤是从朝上的两堆牌中挑选比较小的一张,将该牌从堆中移开。为避免每次都检查堆是否为空,在每个堆底部放一张哨兵牌:inf。

时间复杂度:O(nlgn)

def merge(A, p, q, r):
    n1 = p-q+1
    n2 = r - q
    L = 0 * [n1+1]
    R = 0 * [n2+1]
    for i in range(1, n1):
        L[i] = A[p+i-1]
    for j in range(1, n2):
        R[j] = A[q+j]
    L[n1+1] = sys.maxint   #inf
    R[n2+1] = sys.maxint   #inf
    i = 1
    j = 1
    for k in range(p,r):
        if L[i] <= R[j]:
            A[k] = L[i]
            i += 1
        else:
            A[k] = R[j]
            j = j + 1
            
def merge-sort(A, p, r):
    if p < r:
        q = (p + r)/2
        merge-sort(A, p, q)
        merge-sort(A, q+1, r)
        merge(A, p, q, r)


3. 堆排序

时间复杂度:O(nlgn) 具有空间原址性,需要常数个临时存储空间

二叉堆是一个数组

二叉堆分为最大堆和最小堆

最大堆:除了根节点外所有结点i都满足   A[parent(i)] >= A[i]------》在堆排序算法中使用

最小堆:除了根节点外所有结点i都满足   A[parent(i)] <= A[i]------》用于构建优先队列

def parent(i):
    return i/2
    
def lift(i):
    return 2i
    
def right(i):
    return 2i + 1

'''
维护最大堆的性质,输入为一个数组A, 和一个下标i.
在调用max-heapify时,假定根节点为left(i), right(i)的二叉树都是最大堆
但这是A[i] 有可能小于其他孩子,这就违背了最大堆的性质,此方法通过让A[i]
逐级下降,使下标i为根节点的子树重新遵循最大堆的性质
'''    
def max-heapify(A, i):
    l = left(i)
    r = right(i)
    if l <= A.length() and A[l] > A[i]:
        largest = l
    else:
        largest = i
    if r <= A.length() and A[r] > A[largest]:
        largest = r
    if largest != i:
        temp = A[i]
        A[i] = A[largest]
        A[largest] = temp
        max- heapify(A, largest) 

'''
建堆:对树中的其他结点都调用一次max-heapify
'''   
def build-max-heap(A):
    A.heap-size = A.length()
    for i in range(A.heap-size, 1):
        max-heapify(A, i)
        
'''
堆排序算法
'''
def heapsort(A):
    build-max-heap(A)
    for i in range(A.length(), 2):
        temp = A[1]
        A[1] = A[i]
        A[i] = temp
        A.heap-size = A.heap-size - 1
        max-heapify(A, 1)
        
        
4. 快速排序
时间复杂度:O(nlgn) (期望)
            原址性
def quicksort(A, p ,r):
    if p < r:
        q = partition(A, p ,r)
        quicksort(A, p ,q-1)
        quicksort(A, q+1, r)
        
def partition(A, p, r):
    x = A[r]
    i = p - 1
    for j in range(p, r-1):
        if A[j] <= x:
            i = i + 1
            exchange A[i] with A[j]
    exchange A[i+1] with A[r]
    return i+1

1、2、3、4比较排序
5、6、7 线性时间排序

5. 计数排序

基本思想:对每一个输入元素x,确定小于x的元素个数。利用这一信息,就可以直接把x放到它在输出数组中的位置上。在计数排序算法中,输入A[1,,,,n] A.length() = n。还需要两个数组 B[1,,,,,n]存放排序的输入, C[0,k] 提供临时存储空间

def counting-sort(A, B, k):
    C = (k+1) * [0]    #初始化一个数组C[0,,,,k]
    for j in range(1, A.length()):     
        C[A[j]] = C[A[j]] + 1            #C[i]表示等于i元素的个数
    for i in range(1, k):
        C[i] = C[i] + C[i-1]             #计算有多少元素小于等于i
    for j in range(A.length(), 1):
        B[C[A[j]]] = A[j]
        C[A[j]] = C[A[j]] - 1


6. 基数排序

假设n个d位元素存放在数组A中,1是最低位,d是最高位

def radix-sort(A, d):
    for i in range(1, d):
        use a stable sort to sort array A on digit


7. 桶排序

def bucket-sort(A):
    n = A.length()
    B = n * [0]
    for i in range(1, n):
        insert A[i] into B[nA[i]]
    for i in range(0, n-1):
        sort list B[i] with inserton sort
    concatenate the list B[0],B[1],....B[n] together in order


你可能感兴趣的:(排序)