Python implements binary heap and python implements binary

Source: Internet
Author: User

Python implements binary heap and python implements binary

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.

Figure 1: Complete Binary Tree

Interestingly, we can use a single list to implement a full tree. We do not need to use nodes, references, or nested lists. For a Complete Binary Tree, if the subscript of a node in the list is p, the subscript of the Left subnode is 2 p, and the right node is 2 p + 1. When we want to find the parent node of any node, we can directly use the python division. If the node is markednThe parent node subscript isn//2. Figure 2 shows a list representation of a Complete Binary Tree and tree. Note the relationship between the parent node and the child node 2 p and 2 p + 1. The list representation of the full tree combines the features of the full binary tree, so that we can use a simple mathematical method to efficiently traverse a full tree. This also enables us to efficiently implement the binary heap.

Nature of heap order

The method for storing elements in the heap depends on the heap sequence. The heap sequence refers to the key value of any node x in the heap, and the key value of its parent node p is smaller than or equal to x. Figure 2 shows a complete binary tree with a heap sequence.

Figure 2: Full tree and Its list Representation

Implementation of binary heap operations

Next we will construct a binary heap. Because you can use a list to save the heap data, the constructor only needs to initialize a list andcurrentSizeTo indicate the current heap size. Listing 1 shows the python code for constructing a binary heap. Note thatheaplistIt is not used, but we still keep it for the convenience of the code behind division.

Listing 1

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.

Figure 3: The new node is "floating" to its correct position

When we make an element "floating", we need to ensure the heap order between the new node and the parent node and other sibling nodes. Of course, if the new node is very small, we still need to switch it to another layer. In fact, we need to keep switching until we reach the top of the tree. Listing 2 shows the "floating" method, which "floats" A new node to its correct position to satisfy the heap order. This is a good exampleheadlistThe importance of element 0 that is not used in. In this way, we only need to perform simple division and divide the subscript of the current node by 2, so that we can calculate the parent node of any node.

In Listing 3, we can writeinsertMethod code.insertA large part of the work ispercUpFunction completed. When a new node is added to the treepercUpYou can place the new node in the correct position.

Listing 2

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.

Figure 4: Root Node sinking after replacement

To maintain the heap order, we need to "sink" The New root node along a path until it is smaller than the two subnodes. When selecting a sinking path, if the new root node is larger than the child node, select a smaller child node to exchange with it. As shown in Listing 4, the new node is required to sink.percDownAndminChildMethod code.

Listing 4

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

Figure 5: generate a binary heap for the list [9, 6, 5, 2, 3]

Figure 5 shows the usagebuildHeapMethod[ 9, 6, 5, 2, 3]The switch operation performed when the node in is moved to the correct position. Although we start from the middle of the tree and go back to the root nodepercDownThe method ensures that the largest subnode is always "sunk ". Because the heap is a Complete Binary Tree, any node in the middle is a leaf node, so there is no subnode. Note that wheni=1We sink from the root node, which requires a lot of switching operations. We can see that the two trees on the rightmost side of Figure 5 are first removed from the root node and moved to the next layer,percDownFurther check its subnode at this time to ensure that it can no longer be dropped until it is dropped to the correct position. Then perform the second exchange, 9 and 3. As 9 has been moved to the bottom layer of the tree, further exchange is impossible. It is helpful to compare the list representation and a series of exchanges with the tree representation shown in Figure 5.

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.

Articles you may be interested in:
  • Python binary tree implementation example
  • Implementation of python binary tree traversal
  • Introduction to python Data Structure Tree and binary tree
  • Example of building a binary tree in python Data Structure
  • Python Data Structure-binary tree traversal instance
  • Implement Binary Search Tree in Python

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.