Data structure - the maximum and minimum heap

Heap Introduction

Heap (Heap) is a tree structure, it is a complete binary tree, a minimum or maximum heap heap will always meet the following conditions:

  • The value of a stack node is always greater than or less than the value of its parent
  • Heap always a complete binary tree

One of the biggest heap as follows:
The maximum heap
the maximum value in the root node, any node is always greater than the maximum value of the sub-tree, and the minimum heap on the contrary
say so many things about the definition of the heap, we find that the nature of the heap or mentioned in the previous chapter binary, the binary heap carry out separate from naturally many space applications
the most common, priority queue, can be implemented by the maximum stack structure, another example can be used to handle a minimum heap problem top k

Realization of ideas

Introduced above, the heap is a complete binary tree, if we start from the root to each node are numbered as follows:
hey
by mathematical induction, for any node number k:

  • Parent Id = (k-1) // 2
  • The left child node number = k * 2 + 1
  • Right child node number = (k + 1) * 2

Since we can pass any number k, find it in the parent-child node number, which means you can use an array to store node, which is the heap and other tree structure is quite different from the underlying implementation
Generally speaking, a linked list or a tree, different nodes are dependent on each other between a reference node to ensure the integrity of the data structure, but for the heap for as long as we have access to the parent-child node by index on it (in fact, for any of a complete binary tree, it can use an array to to ensure data integrity, but the lack of application of significance)

Using arrays as storage structure can guarantee that it is a complete binary tree, add or delete the data you need to ensure that the value of a node is always the heap is not less than the value of its parent node (where the maximum stack, for example)
is usually a maximum heap, not design to modify data and query data (in fact, it is easy to query and modify the index data by any node)
for increasing data, new data can be inserted into the end of the array and get the index through the index to find the parent, if the parent node is greater than the value of the switching position, the above-described operation is repeated until the parent node is greater than the new data is stopped.
For node deletes the data, deleting the index k, we can last array element and to a position index k, and then compare it to the left and right child nodes maximum value, is less than the switching position, can repeat the above operation.

Specific code

Maxheap class definitions and basic functions

class Maxheap:
    def __init__(self):
        self._data = []  # 存储数据数组

    def _parentId(self, index: int) -> int:
        # 输入子节点的索引返回父节点索引
        return (index - 1) // 2 if index > 0 else 0

    def _leftId(self, index: int) -> int:
        # 输入父节点的索引返回左子节点索引
        return 2 * index + 1

    def _rightId(self, index: int) -> int:
        # 输入父节点的索引返回右子节点索引
        return 2 * index + 2

    @staticmethod
    def _cmp_(m, o):
        # 比较函数 修改_cmp_可实现最小堆
        return m > o

Explain _cmp_ () method, which is used to customize the user how to compare, if a heap memory is digital, then the comparison operators can solve the problem, but if the store is user-defined class instance, and implement python class and no built-in method of comparison, this time the user can change the _comp_ methods to customize the size comparison
to a maximum heap new element

    def add(self, item):
        # 向添加一个元素
        # 思路:首先添加在数据最末尾 然后比较它的父节点 如果大于父节点 则交换两个节点位置 继续比较
        self._data.append(item)
        index = len(self._data) - 1
        while self._cmp_(item, self._data[self._parentId(index)]):
            # 交换位置
            self._data[index], self._data[self._parentId(index)] = self._data[self._parentId(index)], self._data[index]
            index = self._parentId(index)

Remove the maximum

    def get(self):
        # 取出堆中的最大值 也就是数组序号为0的值
        # 后续处理思路:把数组最后一个元素插入到第一个元素,比较它和子节点的值,如果小于,则交换
        if not self._data:
            raise BlockingIOError
        res = self._data[0]
        if len(self._data) == 1:
            self._data = []
            return res
        self._data[0] = self._data.pop()
        index = 0
        # 先判断有没有子节点
        while True:
            rightId = self._rightId(index)
            leftId = self._leftId(index)
            if len(self._data) >= rightId:
                # 找出左右节点最大值
                if len(self._data) == rightId or self._cmp_(self._data[leftId], self._data[rightId]):
                    swapId = leftId
                else:
                    swapId = rightId
                if self._cmp_(self._data[swapId], self._data[index]):
                    self._data[index], self._data[swapId] = self._data[swapId], self._data[index]
                    index = swapId
                else:
                    break
            else:
                # 没有子节点 不用比较了 退出循环
                break
        return res

This is the code to integrate the above paragraphs, one of the biggest heap is realized, although I did not realize the function delete any node, but to achieve and get methods are the same, interested friends can try to write about yourself remove (k) method

Expansion and other

In principle and in terms of the amount of code, I believe that a good understanding of the heap, in front of several data structures we mentioned queue and stack can be used to implement a priority queue, we welcome the freedom to try

Guess you like

Origin www.cnblogs.com/lazyfish007/p/12239947.html