《我的第一本算法书》堆的Python实现

《我的第一本算法书》堆的Python实现

堆是一种树形结构,每个结点最多有两个子结点。
在这里插入图片描述

排列顺序是【1, 3, 6, 4, 8, 7】
相应下标号【0, 1, 2, 3, 4, 5】

可见下标号为 i 的结点左节点下标为 2i + 1,右结点下标为 2i + 2

一、建立寻找左、右结点的方法:

def getLeft(arr, index):
    position = 2 * index + 1
    if len(arr) > position:
        return arr[position]
    else:
        return None


def getRight(arr, index):
    position = 2 * index + 2
    if len(arr) > position:
        return arr[position]
    else:
        return None

用List定义一个堆,添置一些数据,调用方法查询1、 3、 7的子结点:

    array = [1, 3, 6, 4, 8, 7]
    print(getLeft(array, array.index(1)), getRight(array, array.index(3)), getLeft(array, array.index(7)))

输出结果:

3 8 None

二、建立寻找父结点的方法:

def getHead(arr, index):
    if index % 2 == 0:
        # 偶数
        if index == 0:
            return None
        return arr[int((index - 2)/2)]
    else:
        return arr[int((index - 1)/2)]

查询7的父结点

    print(getHead(array, array.index(7)))

输出结果:

6

三、堆的排序

堆的存储规则是子结点必定大于父结点,添加结点的顺序是从最下方的左侧开始。

例如,上方实例堆添加一个数据5
在这里插入图片描述

父结点大于子结点,交换它们的位置,直至满足排序规则:
在这里插入图片描述

建立排序方法:

def sortHeap(arr):
    for index, value in enumerate(arr):
        left = getLeft(arr, index)
        if left:
            if left < arr[index]:
                arr[2 * index + 1], arr[index] = arr[index], left
        right = getRight(arr, index)
        if right:
            if right < arr[index]:
                arr[2 * index + 2], arr[index] = arr[index], right

四、增加数据

使用List的append方法。

    array = [1, 3, 6, 4, 8, 7]
    
    array.append(5)
    print(array)
    sortHeap(array)
    print(array)

输出结果:

[1, 3, 6, 4, 8, 7, 5]
[1, 3, 5, 4, 8, 7, 6]

五、取出(删除)数据

堆取出最顶上的数据,然后将最后一位数据置顶
建立取出数据并重新排序的方法:

def heapPop(arr):
    tmp = arr[0]
    arr[0] = arr[-1]
    arr.pop()
    sortHeap(arr)
    return tmp

调用方法:

    print(heapPop(array), array)

输出结果:

1 [3, 4, 5, 6, 8, 7]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值