005-Linear Sorting

78 阅读1分钟

Comparison Sort Lower Bound

leaves' number:

For permutaion, n!n! results,leaf represents result.

Time:

n!=n(n1)(n1)...21n(n1)...n2n2n2n!=n\cdot (n-1)\cdot (n-1) ... 2\cdot 1\ge n\cdot (n-1)\cdot ...\cdot {\frac {n}{2}}\ge {\frac{n}{2}} ^ {\frac{n}{2}}
log(n!)log(n2n2)=Ω(nlogn)log(n!)\ge log({\frac{n}{2}} ^ {\frac{n}{2}})={\Omega}(nlogn)


Merge sort is optional in comparison model.O(nlogn)

Code:

def direct_access_sort(A):
    u = 1 + max(x.key for x in A)
    D = None * u
    for x in A:
        D[x.key] = x
    i = 0
    for key in range(u):
        if D[key] is not None:
            A[i] = D[key]
            i += 1

key code:

D[x.key] = x,thus that, the item in D form A array is sorted by the idex of D if D[key] is not None ,skip the empty item in D array

Limitation:

only the item is unique,and the key is not too huge,like u=Ω(n2)u=\Omega(n^2)
(how to solve this problem?)->Tuple Sort

Tuple Sort:

For large item , break up it.
(a,b)=divmod(k,n)(a,b)=divmod(k,n),a=k // n,b= k mod n

eg.:


[17, 3, 24, 22, 12] ⇒ [(3,2), (0,3), (4,4), (4,2), (2,2)] ⇒ 32, 03, 44, 42, 22,we can see that,item is represented by base-5 number

order :

Least significant to most significant!
[32, 03, 44, 42, 22] =⇒ [42, 22, 32, 03, 44] =⇒ 03, 22, 32, 42, 44

problem:

many items have same a or b,even though inputs are distinct.how to solve?
We want to a stable algorithm,but direct access array cannot sort repeated keys-->Counting Sort

Counting Sort:

  • Instead of storing a single item,store a chain ,like hashing.
  • For stability, chain structure should remember the order of inserting
  • insert_last to th end

Advantage:

To store the items with same key.

Code:

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
            x += 1

Radix Sorting:

  • Use tuple sort with counting sort
  • First sort least significant key b,then sort most significent key a
  • Stability ensures sorts stay sorted
  • Running time:O(2n)=O(n)O(2n)=O(n)

Code:

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
            x += 1

def radix_sort(A):
    n=len(A)
    u=1+max(x.key for x in A)
    c=1+(u.bit_length()//n.bit_length())
    class Obj:pass
    D=[Obj() for a in A]
    for i in range(n):
        D[i].digits=[]
        D[i].item=[]
        high=A[i].key
        for j in range(c):
            high, low =divmod(high,low)
            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