How to implement binary heap in Python

Source: Internet
Author: User
A binary heap is a special heap. a binary heap is a completely binary tree (binary tree) or an almost completely binary tree (binary tree ). There are two types of binary heap: maximum heap and minimum heap. Max heap: the key value of the parent node is always greater than or equal to the key value of any subnode; min heap: the key value of the parent node is always less than or equal to the key value of any subnode. A binary heap is a special heap. a binary heap is a completely binary tree (binary tree) or an almost completely binary tree (binary tree ). There are two types of binary heap: maximum heap and minimum heap. Max heap: the key value of the parent node is always greater than or equal to the key value of any subnode; min heap: the key value of the parent node is always less than or equal to the key value of any subnode.

Dual-stack implementation of priority queue

In the previous chapter, we learned "first-in-first-out "(FIFO) Data structure: Queue (Queue). The queue has a variant called "priority queue "(Priority Queue). Priority queue (Dequeue) The operation is the same as that of the queue. However, in the priority queue, the order of elements is determined by the "priority": elements with a higher priority rank first, while those with a lower priority rank later. In this way (Enqueue) Operations are complex. you need to prioritize the elements in the queue as much as possible. We will find that the priority queue in the graph algorithm to be learned in the next section is a useful data structure.

We naturally think of using sorting algorithms and queue methods to achieve priority queues. However, the time complexity of inserting an element in the list isO(n)The time complexity of sorting the list isO(nlogn). We can use other methods to reduce the time complexity. A classic method for implementing the priority queue is to use a binary heap (Binary Heap). The binary heap can maintain the complexity of queuing and queuing.O(logn).

The interesting thing about the binary heap is that its logical structure is like a binary tree, but it is implemented using a non-nested list. There are two kinds of binary heap: the key value is always the smallest in the first line (min heap) ", Otherwise, the key value is always the largest in the first line called" the maximum heap (max heap)". In this section, we use the minimum heap.

Binary heap operations

The basic operations of a binary heap are defined as follows:

  1. BinaryHeap(): Create an empty binary heap object

  2. insert(k): Add new elements to the heap

  3. findMin(): Returns the minimum item in the heap. the minimum item is retained in the heap.

  4. delMin(): Returns the smallest item in the heap and deletes it from the heap.

  5. isEmpty(): Whether the returned heap is empty

  6. size(): Returns the number of nodes in the heap.

  7. buildHeap(list): Create a new heap from a list containing nodes

The code shown below is an example of a binary heap. We can see that no matter which order we add the elements to the heap, each time we remove the smallest element. Next we will implement this process.


from pythonds.trees.binheap import BinHeapbh = BinHeap()bh.insert(5)bh.insert(7)bh.insert(3)bh.insert(11)print(bh.delMin())print(bh.delMin())print(bh.delMin())print(bh.delMin())

To better implement the heap, we adopt a binary tree. We must always maintain a "balance" of binary trees, so that operations must always be performed on a logarithm order of magnitude. The number of left and right subtrees of the balanced binary tree root node is the same. In the implementation of the heap, we adopt the "full binary tree" structure to achieve an approximate "balance ". A complete binary tree indicates that each internal node tree reaches the maximum value. except for the last layer, only several nodes on the right are missing. Figure 1 shows a complete binary tree.

class BinHeap:  def init(self):    self.heapList = [0]    self.currentSize = 0

What we need to achieve next isinsertMethod. First, the new key value should be added to the end of the list to satisfy the "full binary tree" nature. However, the new key value is simply added at the end of the list, which obviously cannot meet the heap sequence. However, we can resatisfy the heap order by comparing the parent node with the newly added element. If the new element is smaller than the parent node, it can be swapped with the parent node. Figure 3 shows a series of swap operations to "float" the newly added element to the correct position.

def percUp(self,i):  while i // 2 > 0:   if self.heapList[i] < self.heapList[i // 2]:     tmp = self.heapList[i // 2]     self.heapList[i // 2] = self.heapList[i]     self.heapList[i] = tmp   i = i // 2

Listing 3


def insert(self,k):  self.heapList.append(k)  self.currentSize = self.currentSize + 1  self.percUp(self.currentSize)

We have already writteninsertMETHOD. let's take a look.delMinMethod. The heap sequence requires the root node to be the smallest element in the tree, so it is easy to find the smallest element. What is more difficult is how to maintain the heap structure and heap sequence after removing the elements of the root node. we can take two steps. First, replace the root node with the last node. Removing the last node maintains the nature of the heap structure. Such a simple replacement will disrupt the heap sequence. Step 2: "sink" the new node to restore the heap sequence. Figure 4 shows a series of swap operations to "sink" the new node to the correct position.

def percDown(self,i):  while (i * 2) <= self.currentSize:    mc = self.minChild(i)    if self.heapList[i] > self.heapList[mc]:      tmp = self.heapList[i]      self.heapList[i] = self.heapList[mc]      self.heapList[mc] = tmp    i = mcdef minChild(self,i):  if i * 2 + 1 > self.currentSize:    return i * 2  else:    if self.heapList[i*2] < self.heapList[i*2+1]:      return i * 2    else:      return i * 2 + 1

As shown in Listing 5delMinOperation Code. We can see that a helper function is used to handle the problem, that ispercDown.

Listing 5


def delMin(self):  retval = self.heapList[1]  self.heapList[1] = self.heapList[self.currentSize]  self.currentSize = self.currentSize - 1  self.heapList.pop()  self.percDown(1)  return retval

The last part of the binary heap is to find a method to generate a "heap" from the unordered list. The first thing we think of is to insert each element in the unordered list into the heap in sequence. For a sorted list, we can use binary search to find the proper position and insert the key value to the heap at the next position. The time complexity isO(logn). To insert an element to the list, you need to move some other elements in the list to create a new node. The time complexity isO(n). ThereforeinsertThe total overhead of the method isO(nlogn). In fact, we can directly generate a heap for the entire list and control the total overhead inO(n). Listing 6 shows the heap generation operation.

Listing 6


def buildHeap(self,alist):  i = len(alist) // 2  self.currentSize = len(alist)  self.heapList = [0] + alist[:]  while (i > 0):    self.percDown(i)    i = i - 1

i = 2 [0, 9, 5, 6, 2, 3]i = 1 [0, 9, 2, 6, 5, 3]i = 0 [0, 2, 3, 6, 5, 9]

The following code is a fully binary heap implementation.


def insert(self,k):   self.heapList.append(k)   self.currentSize = self.currentSize + 1   self.percUp(self.currentSize)  def percDown(self,i):   while (i * 2) <= self.currentSize:     mc = self.minChild(i)     if self.heapList[i] > self.heapList[mc]:       tmp = self.heapList[i]       self.heapList[i] = self.heapList[mc]       self.heapList[mc] = tmp     i = mc  def minChild(self,i):   if i * 2 + 1 > self.currentSize:     return i * 2   else:     if self.heapList[i*2] < self.heapList[i*2+1]:       return i * 2     else:       return i * 2 + 1  def delMin(self):   retval = self.heapList[1]   self.heapList[1] = self.heapList[self.currentSize]   self.currentSize = self.currentSize - 1

You canO(n)It seems incredible that the binary heap can be generated under the overhead, which proves that it is beyond the scope of this book. HoweverO(n)The key to generating a pile of overhead is thatlognThe factor is based on the tree height. ForbuildHeapMany operations in, tree height ratiolognSmall.

The above is the details about how to implement the binary heap in Python. For more information, see other related articles in the first PHP community!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.