python 实现堆

堆:是一个完全二叉树,有大根堆跟小根堆的区别。
大根堆最大数在根节点(即最上方),他的子树也都是大根堆。小根堆同理,最小数在根节点。
堆排序:只用把根节点取出,再把最后一个节点放入根节点的位置,然后进行排序,排序的方式是(比如大根堆),比较新的根节点跟它的两个子节点的大小,如果比它们其中一个小就跟它互换位置(如果比两个子节点都小则跟最小的那个换),然后去跟新的子节点比较(即递归)。
可以看一下这篇博客,有图解。
python实现:

import copy
class Heap:
    def __init__(self,s):
        self.heap = self.Bulid_Max_Heap(s)

    def Max_heapify(self,heap,heapSize,root):
        left = 2*root+1
        right = 2*root+2
        larger = root
        # print(left, right, root)
        if left <= heapSize and heap[larger] < heap[left]:#如果小于list的长度则进行判断。
            larger = left
        if right <= heapSize and heap[larger] < heap[right]:
            larger = right
        if larger != root:
            heap[larger], heap[root] = heap[root], heap[larger]#相当于如果交换就与最小的那个交换
            # print(heap)
            self.Max_heapify(heap,heapSize, larger)

    def Bulid_Max_Heap(self,heap):
        heapsize = len(heap)-1
        for i in range((heapsize-1)//2,-1,-1):#即从最后一个非叶子节点进行对排序,一直到根节点,确保每一个子堆都是大根堆
            self.Max_heapify(heap,heapsize,i)
        return heap


    def HeapSort(self):
        heap = copy.copy(self.heap)
        for i in range(len(heap)-1,-1,-1):#对大根堆进行排序,即把最大值放到最后,再把最后一个值放到最前,然后进行堆排序,循环,直到list从小到大排好序。
            heap[0],heap[i] = heap[i],heap[0]
            self.Max_heapify(heap,i - 1,0)
        return heap

    def HeapInsert(self, data):
        heap = self.heap
        heap.append(data)

        heapSize = len(heap) - 1
        father = (heapSize - 1)// 2
        son = heapSize
        while father>=0:
            if heap[father] < heap[son]:
                heap[father],heap[son] = heap[son], heap[father]
                son = father
                father = (father -1)//2
            else:
                break
        return heap




if __name__ == '__main__':
    a = [30,50,57,77,62,78,94,80,84]
    heap = Heap(a)
    print(heap.heap)
    print(heap.HeapSort())
    print(heap.HeapInsert(100))
    print(heap.HeapSort())
    print(heap.HeapInsert(90))
    print(heap.HeapSort())
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值