Application of tree -- binary heap to realize priority queue

Previous queues were all first in, first out data structures. However, in the priority queue, the data in the queue has a priority label. In priority queues, the logical order of items in the queue is determined by their priority. The highest priority is in front of the queue and the lowest priority is after the item.

The classic way to implement priority queue is to use a data structure which is a binary heap. It can queue and retrieve queues in O(log(n)) time

What is a binary pile

Binary heap, which is a complete binary tree in structure, uses the array list in implementation, and uses the index value of array to represent the parent and child nodes. There are two common variants of binary heap: the smallest heap, where the smallest key is always in front, and the largest heap.

Since the two fork heap is a complete two fork tree, in order to ensure the time amount of log(n), the tree must be balanced.

As shown in the figure, it is a binary heap, the structure of which is similar to a tree, and the implementation method is implemented by list. The first element of the list is 0, so why? Because every element on the tree has a corresponding index, it is required to satisfy that the left and right nodes are 2 * P & 2 * P + 1 respectively. If the index index starts from 0, it is not satisfied.

The properties of binary heap is a very important thing. All operations of binary heap are basically based on its properties: each node's parent node is smaller than itself (minimum heap)

Construction of binary heap


class BinaryHeap:
    def __init__(self):
        self.__heap_list = [0]
        self.__size = 0

Insertion of binary heap

Insert an item in the binary heap. The process is: put the item to be inserted into the last item in the binary heap list. Because the binary heap needs to keep its attributes (each node's parent node is smaller than itself), this item is compared with its parent node. The smaller one is on the top, and the larger one is on the bottom for possible exchange. This comparison will last until the root node

This exchange is called go because it exchanges the items to be inserted from bottom to top_ Up


    def go_up(self, index):
        while index // 2 > 0:
            if self.__heap_list[index] < self.__heap_list[index // 2]:
                self.__heap_list[index], self.__heap_list[index // 2] = self.__heap_list[index // 2], self.__heap_list[index]

            index = index // 2

    def insert(self, data):
        self.__heap_list.append(data)
        self.__size = self.__size + 1
        self.go_up(self.__size)

Deletion of binary heap

Since we study the minimum heap, the outbound operation is the node with the minimum move out value, that is, the root node.

Specific operation: after removing the root node, place the last item of the list on the root node, and then go according to the properties of the binary heap_ Down operation (i.e. the items of the root node are compared downward in turn)


    def go_down(self, index):
        while index * 2 <= self.__size:
            mc = self.find_min(index)

            if self.__heap_list[index] > self.__heap_list[mc]:
                self.__heap_list[index], self.__heap_list[mc] = self.__heap_list[mc], self.__heap_list[index]

            index = mc

    def find_min(self, index):
        if index * 2 + 1 > self.__size:
            return index * 2
        else:
            if self.__heap_list[index * 2] < self.__heap_list[index * 2 + 1]:
                return index * 2
            else:
                return index * 2 + 1

    def delete(self, data):
        ret_val = self.__heap_list[1]
        self.__heap_list[1] = self.__heap_list[self.__size]
        self.__size = self.__size - 1
        self.__heap_list.pop()
        self.go_down(1)

        return ret_val

Building a binary reactor

Two ideas:

1. The list can be sorted directly, with the lowest cost O(nlogn). The resulting list must be a binary heap

2. For each item in a list, go from left to right_ Down operation, time complexity O(n)


    def delete(self, data):
        ret_val = self.__heap_list[1]
        self.__heap_list[1] = self.__heap_list[self.__size]
        self.__size = self.__size - 1
        self.__heap_list.pop()
        self.go_down(1)

        return ret_val

Complete implementation of binary heap


class BinaryHeap:

    def __init__(self):
        self.__heap_list = [0]
        self.__size = 0

    def go_up(self, index):
        while index // 2 > 0:
            if self.__heap_list[index] < self.__heap_list[index // 2]:
                self.__heap_list[index], self.__heap_list[index // 2] = self.__heap_list[index // 2], self.__heap_list[index]

            index = index // 2

    def insert(self, data):
        self.__heap_list.append(data)
        self.__size = self.__size + 1
        self.go_up(self.__size)

    def go_down(self, index):
        while index * 2 <= self.__size:
            mc = self.find_min(index)

            if self.__heap_list[index] > self.__heap_list[mc]:
                self.__heap_list[index], self.__heap_list[mc] = self.__heap_list[mc], self.__heap_list[index]

            index = mc

    def find_min(self, index):
        if index * 2 + 1 > self.__size:
            return index * 2
        else:
            if self.__heap_list[index * 2] < self.__heap_list[index * 2 + 1]:
                return index * 2
            else:
                return index * 2 + 1

    def delete(self, data):
        ret_val = self.__heap_list[1]
        self.__heap_list[1] = self.__heap_list[self.__size]
        self.__size = self.__size - 1
        self.__heap_list.pop()
        self.go_down(1)

        return ret_val

    def build_heap(self, alist):
        index = len(alist) // 2
        self.__size = len(alist)
        self.__heap_list = [0] + alist[:]

        while index > 0:
            self.go_down(index)
            index = index - 1

Tags: Programming

Posted on Tue, 09 Jun 2020 02:03:46 -0400 by Richard