zoukankan      html  css  js  c++  java
  • python 堆排序

    堆排序是对选择排序的一种优化算法,都属于选择排序类。

    基本过程:堆是一种完全二叉树,是一种树形选择结构,将待排序的序列构造成一个大顶堆(即每个节点的值都大于或等于其左右孩子节点的值),然后将堆顶的根节点移走,与堆数组的末尾元素交换,此时末尾元素就是最大值。再将剩余的n-1个序列重新构造一个堆,得到次大值置于末尾,反复执行得到一个有序序列。

    过程可参考如下图:

                                    

    这里需要注意的,堆排序为了方便完全二叉树的计数,序列的首位置为空,忽略不计。

    示例代码如下:

    def heap_sort(lst):
        n = len(lst)-1              # 这里注意根据python的range列表的性质,要将序列长度减一,否则列表长度溢出
        for i in range(n/2, 0, -1):
            heap_adjust(lst, i, len(lst))
    
        while n > 1:
            lst[1], lst[n] = lst[n], lst[1]   # 将堆顶记录和当前未经排序子序列的最后一个记录交换
            heap_adjust(lst, 1, n)            # 将lst[n]重新调整为大顶堆
            n -= 1
        return lst[1:]                      # 这里为了方便完全二叉树的计数,将序列中的首个元素置为空忽略不计
    
    def heap_adjust(lst, k, size):      # 自顶向下堆化,从k开始堆化
        N = size - 1
        while 2 * k <= N:
            lchild = 2 * k
            rchild = 2 * k + 1
            if lchild < N and lst[lchild] < lst[rchild]:  # 选出左右孩子节点中更大的那个,并将关键字赋值给左孩子
                lchild = rchild
            if lst[k] < lst[lchild]:                      # 将左孩子与父节点比较,选出大的
                lst[k], lst[lchild] = lst[lchild], lst[k]
                k = lchild              # 将k扩倍,对孙节点排序
            else:
                break
    
    
    if __name__ == "__main__":
        start = time.clock()
    
        rand_lst = []
        for i in range(10):
            rand_lst.append(round(random.random()*100, 2))
        lst = heap_sort(rand_lst)
    
        end = time.clock()
        print lst
        print "done  ", (end-start)

    性能方面:

    堆排序的运行时间主要消耗在初始构建堆和重建堆的反复筛选上

    由于堆排序对原始记录的排序状态并不敏感,因此它无论是最好、最坏和平均时间复杂度都为O(nlogn),空间复杂度上它只有一个用来交换的暂存单元,所以为O(1),但是由于记录的比较和交换是跳跃进行的,所以堆排序是不稳定的排序方法。此外,由于它的性能主要消耗在堆的创建与重建上,所以不适合排序序列少的情况。

  • 相关阅读:
    用ildasm和ilasm对.net下的exe程序进行破解初探
    随笔--各种概念等等
    C#高级编程学习一-----------------第五章泛型
    visual studio相关操作
    webservice开发
    delphi各种错
    android开发文章收藏
    android开发遇到的问题
    android应用开发基础知道
    数据库各种问题
  • 原文地址:https://www.cnblogs.com/webber1992/p/6140850.html
Copyright © 2011-2022 走看看