|
@ -0,0 +1,118 @@ |
|
|
|
|
|
// 20:50
|
|
|
|
|
|
// 22:31
|
|
|
|
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
|
|
|
|
const int N = 1000; |
|
|
|
|
|
|
|
|
|
|
|
class BigHeap { |
|
|
|
|
|
private: |
|
|
|
|
|
int *_internal_array; |
|
|
|
|
|
int len = 0; |
|
|
|
|
|
bool external = false; |
|
|
|
|
|
|
|
|
|
|
|
int get_left_child(int index) { |
|
|
|
|
|
return this->_internal_array[index * 2]; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int get_right_child(int index) { |
|
|
|
|
|
return this->_internal_array[index * 2 + 1]; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int get_parent(int index) { |
|
|
|
|
|
return this->_internal_array[index / 2]; |
|
|
|
|
|
} |
|
|
|
|
|
void adjust_up(int index) { |
|
|
|
|
|
while (index > 1 && this->_internal_array[index] > this->get_parent(index)) { |
|
|
|
|
|
std::swap(this->_internal_array[index], this->_internal_array[index / 2]); |
|
|
|
|
|
index /= 2; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void adjust_down(int index) { |
|
|
|
|
|
while (index * 2 <= this->len) { |
|
|
|
|
|
int target = index; |
|
|
|
|
|
if (this->_internal_array[target] < this->get_left_child(index)) // 如果左节点更大
|
|
|
|
|
|
target = index * 2; // 左节点换上来
|
|
|
|
|
|
if (index * 2 + 1 <= this->len && this->_internal_array[target] < this->get_right_child(index)) // 如果右节点更大
|
|
|
|
|
|
target = index * 2 + 1; // 右节点换上来
|
|
|
|
|
|
if (index == target) |
|
|
|
|
|
break; |
|
|
|
|
|
// 如果满足了当前节点比左右子节点大,就不用继续下沉了
|
|
|
|
|
|
|
|
|
|
|
|
std::swap(this->_internal_array[index], this->_internal_array[target]); |
|
|
|
|
|
index = target; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
// 好像不太对,算了不用了,叶子节点直接判断就行了
|
|
|
|
|
|
int get_last_non_leaf_index(int len) { |
|
|
|
|
|
int pow_of_2 = 1; |
|
|
|
|
|
int times = 0; |
|
|
|
|
|
while (pow_of_2 < len) { |
|
|
|
|
|
pow_of_2 *= 2; // 也可以写成 pow_of_2 <<= 2;
|
|
|
|
|
|
times++; |
|
|
|
|
|
} |
|
|
|
|
|
return times; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
|
BigHeap() { // 构造函数,在初始化时被调用
|
|
|
|
|
|
this->_internal_array = new int[N]; |
|
|
|
|
|
} |
|
|
|
|
|
BigHeap(int *external_array, int len) { // 也是构造函数,但是使用外部的数组初始化,数组要从1开始
|
|
|
|
|
|
this->_internal_array = external_array; |
|
|
|
|
|
this->len = len; |
|
|
|
|
|
for (int i = this->len; i >= 1; i--) { |
|
|
|
|
|
adjust_down(i); |
|
|
|
|
|
} |
|
|
|
|
|
this->external = true; |
|
|
|
|
|
} |
|
|
|
|
|
~BigHeap() { // 析构函数,在对象被删除时被调用
|
|
|
|
|
|
if (!this->external) |
|
|
|
|
|
delete this->_internal_array; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int get_length() { |
|
|
|
|
|
return this->len; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void insert(int num) { |
|
|
|
|
|
this->_internal_array[++this->len] = num; |
|
|
|
|
|
int index = this->len; |
|
|
|
|
|
adjust_up(index); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int pop() { |
|
|
|
|
|
int result = this->_internal_array[1]; |
|
|
|
|
|
this->_internal_array[1] = this->_internal_array[this->len--]; |
|
|
|
|
|
adjust_down(1); |
|
|
|
|
|
return result; |
|
|
|
|
|
} |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
int a[N]; |
|
|
|
|
|
int len; |
|
|
|
|
|
|
|
|
|
|
|
int main() { |
|
|
|
|
|
std::cin >> len; |
|
|
|
|
|
for (int i = 1; i <= len; i++) |
|
|
|
|
|
std::cin >> a[i]; |
|
|
|
|
|
|
|
|
|
|
|
BigHeap big_heap_internal; |
|
|
|
|
|
for (int i = 1; i <= len; i++) { |
|
|
|
|
|
big_heap_internal.insert(a[i]); |
|
|
|
|
|
} |
|
|
|
|
|
std::cout << "逐个插入后,逐个弹出输出的结果为:" << std::endl; |
|
|
|
|
|
while (big_heap_internal.get_length() > 0) { |
|
|
|
|
|
std::cout << big_heap_internal.pop() << " "; |
|
|
|
|
|
} |
|
|
|
|
|
std::cout << std::endl; |
|
|
|
|
|
|
|
|
|
|
|
BigHeap big_heap_external(a, len); |
|
|
|
|
|
std::cout << "一次性初始化后,逐个弹出输出的结果为:" << std::endl; |
|
|
|
|
|
while (big_heap_external.get_length() > 0) { |
|
|
|
|
|
std::cout << big_heap_external.pop() << " "; |
|
|
|
|
|
} |
|
|
|
|
|
std::cout << std::endl; |
|
|
|
|
|
return 0; |
|
|
|
|
|
} |