树形结构:优先级队列,堆

102 篇文章 0 订阅
70 篇文章 0 订阅

优先级队列,堆是比较常用的数据结构,分支限界法,贪心法均会用到优先级队列

有必要了解一下优先级队列的实现方式

# -*- coding: utf-8 -*-

# 最大堆

# 很显然这是一个双针模型,指着一对父子,父亲小于儿子,则儿子上位
def siftUp(arr,insert_index,insert_value):
    child_pointer = insert_index
    parent_pointer = (child_pointer-1)//2
    pivot = insert_value
    
    #儿子不断的挑战父亲
    while parent_pointer >=0 and arr[parent_pointer] < pivot:
        arr[child_pointer] = arr[parent_pointer]
        child_pointer = parent_pointer
        parent_pointer = (child_pointer-1)//2
    
    arr[child_pointer] = pivot

def siftDown(arr,insert_index,insert_value):
    end_index = len(arr)-1
    # 下沉也是双针模型,父亲每次和儿子里面最大的交换,逐步下沉
    parent_pointer = insert_index
    child_pointer = 2*parent_pointer + 1
    pivot = insert_value
    
    while child_pointer <= end_index:
        # child_pointer指针总是指向儿子里面最大的那个
        if child_pointer + 1 <= end_index and arr[child_pointer + 1] >arr[child_pointer]:
            child_pointer +=1
        # 假如父亲还是大于两个儿子,就没必要执行下沉操作
        if pivot >= arr[child_pointer]:
            break
        # 否则的话,和最大的儿子交换,逐步下沉,下沉时逐步更新父子指针
        else:
            arr[parent_pointer] = arr[child_pointer]
            parent_pointer = child_pointer
            child_pointer = 2*parent_pointer + 1
    # 把最后空出来的位置进去 ,最后肯定parent_pointer为空,child_pointer越界       
    arr[parent_pointer] = pivot
           

# 上浮构造的时候,就需要从头到尾上浮,每个元素浮一遍    
def buildHeapBySiftUp(arr):
    for i in range(len(arr)):
        siftUp(arr,i,arr[i])
# 下沉构造时,需要从尾到头构造,每个元素沉一遍,实际上至多需要沉一半,因为后面一半
# 元素都是叶子
def buildHeapBySiftDown(arr):
    for i in range((len(arr)-1)//2 -1,-1,-1):
        siftDown(arr,i,arr[i])

代码测试

arr =[1,2,3,4,5,6]
buildHeapBySiftUp(arr)
print(arr)
siftDown(arr,0,0)
print(arr)
arr3=[0,1,2,3,4,5,6]
print(arr3)
buildHeapBySiftDown(arr3)
print(arr3)


runfile('D:/share/test/heapqueue.py', wdir='D:/share/test')
[6, 4, 5, 1, 3, 2]
[5, 4, 2, 1, 3, 0]
[0, 1, 2, 3, 4, 5, 6]
[6, 4, 5, 3, 1, 0, 2]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值