码迷,mamicode.com
首页 > 其他好文 > 详细

Priority Queue Implementation

时间:2019-10-17 12:13:00      阅读:76      评论:0      收藏:0      [点我收藏+]

标签:node   std   bre   bsp   cto   amp   lan   utf-8   size   

In this page, I create a class Binary Heap to implement priority queue in C++ and Python. The data structure is same in both programing language as below,

1
2
3
4
* vector(list in python) to store data
* if i is current node:
* 2*i + 1 is the first child, and 2 * i + 2 is right child
* (i - 1) / 2 is the father node

In C++, I impment compare function(amp) to maintain priority of the heap. we also can provide self-define compare function(amp).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

using namespace std;

* vector to store data
* if i is current node:
* 2*i + 1 is the first child, and 2 * i + 2 is right child
* (i - 1) / 2 is the father node
***/
typedef unsigned long ul;
template<class >
class BinaryHeap{
public:
BinaryHeap();
explicit BinaryHeap(vector<T>);
explicit BinaryHeap(bool (*cmp)(const T&, const T&));
explicit BinaryHeap(vector<T>,bool (*cmp)(const T&, const T&));

bool insert(T ele);
void show_queue(){
for(T x : elements){
cout << x << " ";
}
cout << endl;
}
T pop_top();
bool empty();
private:
vector<T> elements;
unsigned long heap_size;
bool (*cmp)(T ele_a, T ele_b);

void shift_up(T, ul);
void shift_down(T, ul);
bool build_heap();
static bool default_cmp(T ele_a, T ele_b);
};

template<class >
BinaryHeap<T>::BinaryHeap() {
heap_size = 0;
this->cmp = default_cmp;
}
template<class >
BinaryHeap<T>::BinaryHeap(bool (*cmp)(const T&, const T&)) {
heap_size = 0;
this->cmp = cmp;
}
template<class >
BinaryHeap<T>::BinaryHeap(vector<T> eles):elements(move(eles)) {
heap_size = elements.size();
this->cmp = default_cmp;
build_heap();
}

template<class >
BinaryHeap<T>::BinaryHeap(vector<T> eles, bool (*cmp)(const T&, const T&)):elements(move(eles)){
heap_size = elements.size();
build_heap();
this->cmp = cmp;
}

template<class T>
bool BinaryHeap<T>::insert(T ele) {
elements.push_back(ele);
heap_size++;

shift_up(ele,heap_size-1);

return true;
}

template<class T>
T BinaryHeap<T>::pop_top() {
if(heap_size <= 0) throw exception();

T leave = elements[--heap_size];
T top = elements[0];
elements.pop_back();

if(heap_size > 1)
shift_down(leave,0);
return top;
}

template<class T>
bool BinaryHeap<T>::empty() {
return heap_size == 0;
}

template<class T>
bool BinaryHeap<T>::build_heap() {
if(heap_size == 0) return true;

unsigned long _first_not_leave = (heap_size - 1) / 2;
for(ul i = _first_not_leave; i >= 0;i--){
shift_down(elements[i],i);
if(i == 0) break; // necessary because unsigned long won't reach -1
}
}
template<class T>
bool BinaryHeap大专栏  Priority Queue Implementationn><T>::default_cmp(T ele_a, T ele_b) {
return ele_a < ele_b;
}

template<class T>
void BinaryHeap<T>::shift_up(T ele, ul pos) {
ul i = pos,j = (pos - 1) / 2;
while(i > 0 and cmp(ele,elements[j])){
elements[i] = elements[j];
i = j;j = (i - 1) / 2;
}
elements[i] = ele;
}
template<class T>
void BinaryHeap<T>::shift_down(T ele, ul pos) {
ul i = pos, j = pos * 2 + 1;
while(j < heap_size){
if(j+1 < heap_size && cmp(elements[j+1],elements[j])) j = j+1;
if(cmp(ele,elements[j])) break;
elements[i] = elements[j];
i = j; j = i*2 + 1;
}
elements[i] = ele;
}
int main() {

vector<int> v{4,6,8,7,4,2,4};
auto *hp = new BinaryHeap<int>(v);

while(!hp->empty()){
cout << hp->pop_top() <<" ";
}
cout << endl;
return 0;
}

The Python version is relatively poor than the previous one. I will enhance it in the future.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# utf-8
# coding in python 3.6
class PriortyQue:
"""
# README
# 使用list存储二叉树
# 大根堆,最大元素在顶端(弹出最大元素),注释部分为维护小根堆
# i结点的父结点位置为(i-1)//2,i结点的左右子结点位置为2*i+1和2*i+2
# 叶子节点 length//2 - 1
"""
def __init__(self, elements):
# 用列表存储树结构
self.elements = list(elements)

# 构建树
if not self.empty():
leng = len(self.elements)
for i in range(leng // 2 - 1, -1, -1):
print(i, leng)
self.arrangeDown(self.elements[i], i, leng)

# 判断是否为空
def empty(self):
return True if self.elements == [] else False

# 添加元素
def push(self, ele):
self.elements.append(ele)
self.arrangeUp(ele, len(self.elements) - 1)

# 推出元素
def pop(self):
if self.empty():
print("Empty Error")
return

elif len(self.elements) == 1:
return self.elements.pop()

cp_elements = self.elements
root = self.elements[0]
ele = cp_elements.pop()
if cp_elements is not []:
self.arrangeDown(ele, 0, len(cp_elements))

return root

"""
维护大根堆
"""
def arrangeDown(self, ele, begin, end):

cp_elements = self.elements
i = begin
j = begin * 2 + 1

while j < end:
# 当前元素已经为三个元素中的最大值
if j + 1 < end and ele > max(cp_elements[j], cp_elements[j + 1]):
break
if j + 1 < end and cp_elements[j] < cp_elements[j + 1]:
j += 1
cp_elements[i] = cp_elements[j]
i = j
j = i * 2 + 1

cp_elements[i] = ele

def arrangeUp(self, ele, last):
cp_elements = self.elements
i = last
j = (last - 1) // 2

while i > 0 and ele > cp_elements[j]:
cp_elements[i] = cp_elements[j]
i = j
j = (i - 1) // 2

cp_elements[i] = ele

if __name__ == '__main__':
"""
Data test
"""
priorityQue = PriortyQue([4,6,8,7,4,2,4])
# priorityQue = PriortyQue([1])
print(priorityQue.elements)
print(priorityQue.pop())
print(priorityQue.elements)
priorityQue.push(100)

while not priorityQue.empty():
print(priorityQue.pop(), end=' ')

Priority Queue Implementation

标签:node   std   bre   bsp   cto   amp   lan   utf-8   size   

原文地址:https://www.cnblogs.com/wangziqiang123/p/11690895.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!