zoukankan      html  css  js  c++  java
  • 二叉堆python实现

    二叉堆是一种完全二叉树,我们可以使用列表来方便存储,也就是说,用列表将树的所有节点存储起来。

    如下图,是小根堆方式的二叉堆,假设父节点的下标为p,则他的左孩子下标为2P+1,右孩子下标为2P+2

    class BuildHeap:
        """构建一个小根堆二叉树
        预先定义一个下标为0的元素,实际没有用途,只是为了方便计算乘除
        假设节点下标为i 父节点下标为i//2 左子节点2i 右子节点2i+1
        不加下标为0时,假设父节点下标i,子节点为2i+1,右子节点2i+2
        """
    
    
        def __init__(self):
            # 下标0的元素没有用,但为了后面代码可以用到简单的整数
            # 乘除法,仍保留它。
            self.heaplist = [0]
            self.current_size = 0
    
        def size(self):
            return len(self.heaplist)
    
        def percUp(self, i):
            """上浮"""
            while i // 2 > 0:
                if self.heaplist[i] < self.heaplist[i // 2]:
                    # 与父节点交换。
                    self.heaplist[i], self.heaplist[i // 2] = self.heaplist[i // 2], self.heaplist[i]
                    i // 2  # 沿路径向上
    
    
        def insert(self, key):
            self.heaplist.append(key)  # 添加到末尾
            self.current_size += 1
            self.percUp(self.current_size)  # 新key上浮
    
    
        def percDown(self, i):
            """下沉"""
            while (i * 2) <= self.current_size:
                mc = self.minChild(i)
                if self.heaplist[i] > self.heaplist[mc]:
                    # 交换,下沉
                    self.heaplist[i], self.heaplist[mc] = self.heaplist[mc], self.heaplist[i]
                i = mc  # 沿路径向下
    
    
        def minChild(self, i):
            """找最小的子节点"""
    
            # 判断叶子节点的情况
            if i * 2 + 1 > self.current_size:
                return i * 2
            # 返回较小的子节点
            elif self.heaplist[i * 2] < self.heaplist[i * 2 + 1]:
                return i * 2
            else:
                return i * 2 + 1
    
    
        def delMin(self):
            """移走整个堆中最小的key:根节点heapList[1]"""
            retval = self.heaplist[1]  # 移走堆顶
            # 最后的叶子节点移到堆顶,然后size-1,把叶子节点删除
            self.heaplist[1] = self.heaplist[self.current_size]
            self.current_size -= 1
            self.heaplist.pop()
            self.percDown(1)  # 新顶下沉
            return retval
    
    
        def buildHeap(self, alist):
            """利用下沉法,构建堆"""
            i = len(alist) // 2  # 从最后节点的父节点开始。
            self.current_size = len(alist)
            self.heaplist = [0] + alist[:]
    
            while i > 0:   
                self.percDown(i)
                i -= 1
            
    import random
    l = [i for i in range(1,6)]
    random.shuffle(l)
    bh = BuildHeap()
    bh.buildHeap(l)
    l_sort = []
    for i in range(1,bh.size()):
        l_sort.append(bh.delMin())
    
    print(l_sort)
  • 相关阅读:
    VS2012 窗口布局, update1 和 英语语言包 离线安装方法
    C/C++ 笔记
    MFC学习笔记
    理解虚基类、虚函数与纯虚函数的概念
    ffmpeg使用
    gif制作 & word2007插入gif
    WIN8电脑开机怎么进入安全模式啊?
    vs2012 win8 64 visual assistX 中文 ??
    21 获取文件大小的方法
    20 线程中添加超时的方法
  • 原文地址:https://www.cnblogs.com/hhsh/p/13612934.html
Copyright © 2011-2022 走看看