Python最大堆排序实现方法

Python最大堆排序实现方法,具体代码如下:
 
# -*- coding: utf-8 -*-
 
def merge_sort(seq, cmp=cmp, sentinel=None):
    """合并排序,伪码如下:
    MERGE(A, p, q, r)
    1  n1 ← q - p + 1 // 前个子序列长度
    2  n2 ← r - q // 后个子序列长度
    3  create arrays L[1..n1+1] and R[1..n2+1] // 创建两数组
    4  for i ← 1 to n1 // 复制前n1个进L
    5    do L[i] ← A[p+i-1]
    6  for j ← 1 to n2 // 复制后n2个进R
    7    do R[j] ← A[q+j]
    8  L[n1+1] ← ∞ // 哨兵值,避免判断
    9  R[n2+1] ← ∞ // sentinel value
    10 i ← 1 // 重置
    11 j ← 1
    12 for k ← p to r // 从首个开始遍历
    13   do if (L[i] <= R[j]) // 比较L与R的最小元素(<=)
    14        then A[k] ← L[i] // L的小时,赋值进A
    15             i ← i + 1 // L后移一位
    16        else A[k] ← R[j] // R的小时,赋值进A
    17             j ← j + 1 // R后移一位
 
    T(n) = θ(n*lgn)
 
    Args:
        seq (Sequence): 一个序列对象。
        cmp (Function): 比较函数。默认为内建函数cmp()。
        sentinel (object): 哨兵值,比较时永远最大。
 
    Returns:
        排序后的序列。
    """
    if (seq == None):
        return None
    if sentinel == None:
        import sys
        sentinel = sys.maxint
 
    p = 0
    r = len(seq) - 1
    q = (r - p) / 2 + p # 奇数时,前子序列多得一项
    # assert p >= 0 and r < len(seq) and p <= q <= r, 'p, q, r unavailable'
 
    def merge(seq, p, q, r):
        n1 = q - p + 1 # 前个子序列长度
        n2 = r - q # 后个子序列长度
 
        if p == q: # 即,n1 == 1 and n2 == 1。前提:在奇数时,前子序列多得一项。
            # 都为1项时,直接比较设值。当然,用以下方式,直接用合并步骤也可以的。
            x, y = seq[p], seq[q+1]
            if cmp(x, y) <= 0:
                seq[p] = x
                seq[q+1] = y
            else:
                seq[p] = y
                seq[q+1] = x
            return
        else:
            # if n1 > 1: # 由于现在明确n1>=n2,这里可以不加这一判断。
            merge(seq, p, (q - p) / 2 + p, q)
            if n2 > 1:
                merge(seq, q + 1, (r - q - 1) / 2 + q + 1, r)
 
        # 合并步骤
 
        L, R = [], []
        for i in range(n1):
            L.append(seq[p+i])
        for j in range(n2):
            R.append(seq[q+j+1])
        L.append(sentinel)
        R.append(sentinel)
 
        i, j = 0, 0
        for k in range(p, r+1):
            x, y = L[i], R[j]
            if cmp(x, y) <= 0:
                seq[k] = x
                i = i + 1
            else:
                seq[k] = y
                j = j + 1
 
    if (r - p + 1 > 1):
        merge(seq, p, q, r)
 
    return seq
 
if __name__ == '__main__':
    import random, timeit
 
    items = range(10000)
    random.shuffle(items)
 
    def test_sorted():
        print(items)
        sorted_items = sorted(items)
        print(sorted_items)
 
    def test_merge_sort():
        print(items)
        sorted_items = merge_sort(items)
        print(sorted_items)
 
    test_methods = [test_sorted, test_merge_sort]
    for test in test_methods:
        name = test.__name__ # test.func_name
        t = timeit.Timer(name + '()', 'from __main__ import ' + name)
        print(name + ' takes time : %f' % t.timeit(1))  转载请注明论文发表http://www.400qikan.com
 

posted on 2013-07-29 14:02  琴深  阅读(655)  评论(0编辑  收藏  举报

导航