Achieve big top of the heap

Achieve big top of the heap

1. What is the heap

Heap structure is a kind of complete binary tree. Heap can be divided into a maximum and minimum heap heap, the difference is the parent node is greater than all the child nodes. Max heap is greater than its parent node's child node, the child node is greater than the minimum stack parent node. Figure have a clear understanding of:

2. heap of representation

Implemented stack may use the list is in accordance with the value of the order of traversal sequence on each node stored in the array. There is a relationship between the parent and child nodes:

 1 parent = (i - 1) // 2 # 取整 2 left = 2 * i + 1 3 right = 2 * i + 2 

Where i represents the index of the array, if the value of the left, right beyond the array index, then the node does not exist.


 

3. heap operation

(1) is inserted into the stack value, sift-up operation:



Add an element to the maximum heap, our approach will add value to the end use of the array when the array realization of direct use append (). This time we need to maintain maximum heap characteristics, as shown below. 90 new values into the first end of the stack, and then compared with the value for the parent node, if the value is greater than the parent node, then the switch position.
The problem here is related to the relationship between parent and child nodes. 

A positional relationship between a parent node # i and the sub-stack nodes left, right of the 
parent = int ((i-1 ) / 2) # rounding 
left = 2 * i +. 1 
right = 2 * i + 2 

positions known child node # j, seeking a position of the parent node 
parent = int ((j-1 ) / 2)

  Recursive manner, comparison up until the root node.

(2) obtain or remove the root node, sift-down operation;



当我们把最大或者最小的值从堆中弹出,为了维持堆的特性,要使用sift-down操作。因为最大堆、最小堆的最值都在根节点,当弹出并返回根节点的值后,为了维持堆的特性,我们先将最后一个位置上的值放到根节点中。然后比较它与它的两个子节点中三个值的大小,选择最大的值放到父节点上。同理,我们这里也是使用递归的方式向下比较。这里涉及到两

个问题:

根据父节点确定子节点的位置:

left = 2 * ndx + 1
right = 2 * ndx + 2

交换位置要满足几个条件条件,比如跟左子节点交换的条件:

  • 存在左子节点,
  • 左子节点大于右子节点,
  • 左子节点大于父节点

4. 堆的实现

代码:

 1 class Array:
 2     def __init__(self, size=32):
 3         self.size = size
 4         self._items = [None] * size
 5 
 6     def __getitem__(self, index):
 7         return self._items[index]
 8 
 9     def __setitem__(self, index, value):
10         self._items[index] = value
11 
12     def __len__(self):
13         return self.size
14 
15     def clear(self):
16         for i in range(self.size):
17             self._items[i] = None
18 
19     def __iter__(self):
20         for item in self._items:
21             yield item
22 
23 
24 class MaxHeap:
25     def __init__(self, maxsize=None):
26         self.maxsize = maxsize
27         self._elements = Array(maxsize)
28         self._count = 0
29 
30     def __len__(self):
31         return self._count
32 
33     def add(self, value):
34         if self._count > self.maxsize:
35             raise Exception('full')
36         self._elements[self._count] = value
37         self._count += 1
38         self._siftup(self._count - 1)
39 
40     def _siftup(self, index):
41         if index > 0:
42             parent = (index - 1) // 2
43             if self._elements[index] > self._elements[parent]:
44                 self._elements[index], self._elements[parent] = self._elements[parent], self._elements[index]
45                 self._siftup(parent)
46 
47     def extract(self):
48         if self._count == 0:
49             raise Exception('empty')
50         value = self._elements[0]
51         self._count -= 1
52         self._elements[0] = self._elements[self._count]
53         self._siftdown(0)
54         return value
55 
56     def _siftdown(self, index):
57         left = 2 * index + 1
58         right = 2 * index + 2
59         largest = index
60 
61         if (left < self._count and self._elements[left] >= self._elements[largest]
62                 and self._elements[left] >= self._elements[right]):
63             largest = left
64         elif right < self._count and self._elements[right] >= self._elements[largest]:
65             largest = right
66         if largest != index:
67             self._elements[index], self._elements[largest] = self._elements[largest], self._elements[index]
68             self._siftdown(largest)
69 
70 
71 if __name__ == '__main__':
72     h = MaxHeap(12)
73     h.add(90)
74     h.add(60)
75     h.add(84)
76     h.add(1)
77     h.add(37)
78     h.add(4)
79     h.add(23)
80     h.add(71)
81     h.add(41)
82     h.add(29)
83     h.add(12)
84     for i in range(11):
85         print(h.extract())

 

Guess you like

Origin www.cnblogs.com/yang-he/p/11407701.html