MIT 6.006 lecture005

85 阅读2分钟

Comparison Sort Lower Bound:

Leaves\ge possible outputs,height is lower boundΩ(logL)\Omega (logL),so worst running time is Ω(logL)\Omega(log L).

For sorting in comparison model ,output is n!n!

Running time is lowwer bound log(n!)log(n/2n/2)=Ω(nlogn)log(n!)\ge log({n/2}^{n/2})=\Omega(nlogn)

So merge sort is optimal in comparison model

Dirrecet Access array:

  1. Suppose all keys are unique and non-negative
  2. insert item in the direct access array in O(n)O(n) time
  3. Return items in order they appear in the dirrect access array in O(u)O(u) time.

If u is θ(n)\theta(n) ,the running time is θ(n)\theta(n)

The problem is that if u is larger range like,u=Ω(n2)u=\Omega(n^2)

def DAA(A):
    u = 1 + max([x.key for x in A])
    D = [None] * u
    # O(n)
    for x in A:
        D[x.key] = x
    i = 0
    # O(u)
    for key in range(u):
        if D[key] is not None:
            A[i] = D[key]
            i += 1
    # Running time: if u=\theta n,running time is O(n)
    # We suppose that u is not large , and keys are begative

Tuple Sort:

Represent the key which is too large with the tuple(a,b), a=k//n,b=k  mod  na = k//n,b=k \;mod\; n.Now,a and b are same samller than n

We want themore significant thing to take precedence,we need to do that thing last.

Stability:

For stability,we need the repeated keys appear same order in inputs.

Counting sort:

use chains to solve repeated keys

def counting_sort(A):
    u = 1 + max([x.key for x in A])  # D数组长度
    D = [[] for i in range(u)]  # 建立D数组,D每个元素也是一个列表

    # 只要键值相同的元素,都将他们按照顺序排入相同的列表
    for x in A:
        D[x.key].append(x)

    i = 0

    # 将D数组中的元素依次按序再赋值回A数组
    for chain in D:
        for x in chain:
            A[i] = D[x]
            i += 1

keeps track of how many keys map to each index

def counting_sort(A):
    u == 1 + max([x.key for x in A])
    D = [0] * u

    for x in A:
        D[x.key] += 1
    for k in range(1, u):
        D[k] += D[k - 1]

    for x in list(reversed(A)):
        A[D[x.key] - 1] = x
        D[x.key] -= 1

Radix_sort:

Tuple sort in digits , using counting sort,from least to most significent digit.

Running time:

n+nlognu,ifuncn+nlog_n u,if u\le n^c,running time is O(n)O(n)

def counting_sort(A):
    u = 1 + max([x.key for x in A])
    D = [[] for i in range(u)]
    for x in A:
        D[x.key].append(x)
    i = 0
    for chain in D:
        for x in chain:
            A[i] = x
            i += 1

def radix_sort(A):
    n=len(A)
    u=1+max([x.key for x in A])
    c=1+(u.bit_len()//n.bit_len())
    class Obj :pass

    D=[OBJ() for a in A]
    for i in range(n):
        D[i].digits=[]
        D[i].item=A[i]
        high=A[i].key
        for j in range(c):
            high,low=divmod(high,n)
            D[i].digits.append(low)
            
    for i in range(c):
        for j in range(n):
            D[j].key=D[j].digits[i]
        counting_sort(D)
    
    for i in range(n):
        A[i]=D[i].item