📜  堆节点的父节点 (1)

📅  最后修改于: 2023-12-03 15:23:41.402000             🧑  作者: Mango

堆节点的父节点

在堆中,每个节点都有一个父节点,除了根节点(即堆顶元素)。父节点的值总是大于或等于它的子节点的值,这种堆被称为大根堆。相反,如果父节点的值总是小于或等于它的子节点的值,那么这种堆被称为小根堆

在实现堆的过程中,常常需要知道一个节点的父节点是哪个,下面介绍两种求堆节点父节点的方法。

1. 数组存储

对于一个以数组存储的堆,可以通过下面的公式获取一个节点的父节点的索引:

parent = (i - 1) // 2

其中,i 是当前节点的索引,// 表示整数除法,即向下取整。这个公式的推导比较简单,可以自己尝试一下。

示例代码:

def get_parent_index(array, i):
    """
    获取 i 节点的父节点索引
    array: 堆数组
    i: 当前节点索引
    """
    return (i - 1) // 2

# 示例
array = [10, 8, 9, 4, 5, 2]
print(get_parent_index(array, 5))  # 2
2. 链表存储

对于一个以链表存储的堆,可以通过下面的方法获取一个节点的父节点:

  • 如果该节点在偶数层(从0开始),则其父节点为当前节点的前一个节点;
  • 如果在奇数层,则父节点为当前节点的前两个节点中的较后一个。

示例代码:

class Node:
    def __init__(self, val):
        self.val = val
        self.left = None
        self.right = None
        self.parent = None

def get_parent_node(node):
    """
    获取节点 node 的父节点
    node: 当前节点
    """
    if node.parent is None:
        return None
    if node.parent.left == node:
        return node.parent
    elif node.parent.right == node:
        if node.parent.parent is None:
            return None
        if node.parent.parent.left == node.parent:
            return node.parent.parent.right
        elif node.parent.parent.right == node.parent:
            return node.parent.parent.left

# 示例
root = Node(10)
root.left = Node(8)
root.right = Node(9)
root.left.left = Node(4)
root.left.right = Node(5)
root.right.left = Node(2)
root.left.parent = root
root.right.parent = root
root.left.left.parent = root.left
root.left.right.parent = root.left
root.right.left.parent = root.right
print(get_parent_node(root.right.left).val)  # 8

以上就是计算堆节点父节点的两种方法。在实际应用中,我们可以根据不同的情况选择合适的方法。