Definition of heap
- Must be a complete binary tree (except for the last layer, each node has two sub-nodes, the last layer can only be missing several right nodes)
- The value of each node in the heap must be >= (large top heap) or <= (small top heap) about the value of the subtree node.
Relations of nodes in heap
- The parent node whose subscript is I is i/2
- When the subscript is i, the left subtree node is 2*i and the right subtree node is 2*i+1.
Complete binary tree characteristics:
If a complete binary tree has n nodes, then from n/2+1 node to n are leaf nodes
Constructing Minimum Binary Reactor
# coding:utf-8 """ //Spatial Complexity: O(1) In-situ Sorting //Time complexity: O(nlogn) //Unstable, because the last node interchanges with the top node of the heap may result in the sequential interchange of the same elements """ class MinHeap(object): """ //Minimum heap """ def __init__(self, nums): self.heap_list = [0] # Fill in 0 position self.size = 0 self.init_heap(nums) def insert(self, data): """ //Insert the element, put it at the end, float up :param num: :return: """ self.heap_list.append(data) self.size += 1 self._go_up(self.size) def _go_up(self, i: int): """ //End element floats up :param i: :return: """ while int(i / 2) > 0: parent = int(i / 2) if self.heap_list[i] < self.heap_list[parent]: self.heap_list[i], self.heap_list[parent] = self.heap_list[parent], self.heap_list[i] i = parent def pop_top(self): """ //Delete the top element of the heap, move to the top with the last value, and float down :return: """ if self.size >= 1: top_value = self.heap_list[1] self.heap_list[1] = self.heap_list[self.size] self.heap_list.pop() self.size -= 1 self._go_down(1) return top_value else: raise Exception("Heap Empty") def _go_down(self, i: int): while (2 * i) <= self.size: min_child_pos = self._get_min_child(i) if self.heap_list[i] > self.heap_list[min_child_pos]: self.heap_list[i], self.heap_list[min_child_pos] = self.heap_list[min_child_pos], self.heap_list[i] i = min_child_pos def _get_min_child(self, i: int): """ //Find out the smaller nodes in the left and right subtrees of the i-node :param i: :return: """ left = 2 * i right = 2 * i + 1 if right > self.size: return left elif self.heap_list[left] < self.heap_list[right]: return left else: return right def init_heap(self, nums: list): """ //Construction heap. Complete binary trees are all leaf nodes from n/2, so only non-leaf nodes need to sink. :param nums: :return: """ start_pos = len(nums) // 2 self.size = len(nums) self.heap_list.extend(nums) while start_pos > 0: self._go_down(start_pos) start_pos -= 1 if __name__ == "__main__": nums = [9, 4, 7, 1, 8, 20] mh = MinHeap(nums) mh.insert(2) mh.insert(17) res = [mh.pop_top() for _ in range(5)] assert res == [1, 2, 4, 7, 8]
application
Priority queue
High Performance Timer
For example, a timer maintains a lot of timing tasks, each task has set a trigger execution time point, the timer every passing a very small unit time (such as 0.1s), will scan the task, if the task is the current time, trigger execution.
It is very inefficient to scan all tasks every 0.1s, so putting all tasks into a minimum heap, the heap top storage is the first task to execute. Timer can get a time interval T according to the execution time of the heap top task, which can be checked directly after T time.Priority queue for crawler tasks
Binary heap is commonly used in the priority queue of crawlers. Tasks are put into the binary heap according to their priority. The scheduler can take the top element of the heap to ensure that the task with the highest priority is obtained.
Using Heap to Find Top K
- How to find the first K big data in an array containing n elements?
Build a K-sized small top heap and traverse the array to compare with the top elements. If it is larger than the top elements, delete the top data and insert the data into the heap. Otherwise, compare the next one. The final K elements in the small top heap are the first K elements.
data
- <>
- <>
- <>