浙大数据结构,最大堆c++实现
#pragma once
#include<iostream>
using namespace std;
class Maxheap {
public:
Maxheap():m_ptr_stack(NULL), m_size(0), m_maxsize(0) {}
Maxheap(int Maxsize);
void Insert(int elem);
void InitHeap(int Maxsize);
bool IsFull();
int PopMax();
void create_heap(int num);
void create_heap(int num, int n);
void arr_print();
private:
void adjust_child_tree(int n);
void adjust_sort(int n);
public:
int* m_ptr_stack;//数组方式实现
int m_size;
int m_maxsize;
};
Maxheap::Maxheap(int Maxsize) :m_size(0) {
InitHeap(Maxsize);
}
bool Maxheap::IsFull() {
if (this->m_size == this->m_maxsize) {
return true;
}
else {
return false;
}
}
void Maxheap::arr_print() {
if (!this->m_size) {
cout << "no elem\n";
}
for (int i = 1; i <= this->m_size; i++) {
cout << this->m_ptr_stack[i] << " ";
}
cout << endl;
}
void Maxheap::InitHeap(int Maxsize) {
this->m_maxsize = Maxsize;
this->m_ptr_stack = new int[this->m_maxsize + 1];
//下标为零的地方存放一个哨兵
m_ptr_stack[0] = 3000;
}
void Maxheap::Insert(int elem) {
if (this->IsFull()) {
cout << "full\n";
return;
}
int pos = this->m_size + 1;
for (; elem > this->m_ptr_stack[pos / 2]; pos = pos / 2) {
//比根节点大的情况
this->m_ptr_stack[pos] = this->m_ptr_stack[pos / 2];
}
//如果小于根节点就可以直接插入
this->m_ptr_stack[pos] = elem;
this->m_size++;
}
//插入时排序插入,复杂度高
void Maxheap::create_heap(int num, int n) {
if (num > this->m_maxsize) {
cout << "fault\n";
}
for (int i = 0; i < num; i++) {
int temp = 0;
cin >> temp;
this->Insert(temp);
}
}
int Maxheap::PopMax() {
if (!this->m_size) {
cout << "not exist\n";
return -1;
}
int max_elem = this->m_ptr_stack[1];
int temp = this->m_ptr_stack[this->m_size--];
int child = 2;
int parent = 1;
for (; parent * 2 <= this->m_size; parent = child) {//用最大堆中最后一个元素从根向下过滤
child = parent * 2;
if ((this->m_ptr_stack[child] < this->m_ptr_stack[child + 1]) && (child != this->m_size)) {
child++;// child最大就是m_size,否则不会进入循环,上面一句话判断child如果等于size,那就没有右儿子,所以child就指向左儿子
}
if (temp >= this->m_ptr_stack[child]) {
break;
}
else {
this->m_ptr_stack[parent] = this->m_ptr_stack[child];
}
}
this->m_ptr_stack[parent] = temp;
return max_elem;
}
//调整堆的实现:递归每一个子树,进行最大根排序
void Maxheap::create_heap(int num) {
//先顺序插入,在调整
for (int i = 0; i < num; i++) {
int temp;
cin >> temp;
this->m_ptr_stack[i + 1] = temp;
}
this->m_size = num;
//递归每一个子树
adjust_child_tree(1);
}
//实现树递归调整
void Maxheap::adjust_child_tree(int parent) {
if (parent * 2 <= this->m_size) {
//递归左右子树
adjust_child_tree(parent * 2);
adjust_child_tree(parent * 2 + 1);//adjust是从内到外,也就是树从下往上实现
adjust_sort(parent);//对一颗树进行排序
}
}
void Maxheap::adjust_sort(int parent) {
int child = 1;
if (parent * 2 < this->m_size) {
child = parent * 2;
if ((this->m_ptr_stack[child] < this->m_ptr_stack[child + 1]) && (child != this->m_size)) {
child++;
}
if (this->m_ptr_stack[parent] >= this->m_ptr_stack[child]) {
return;
}
else {
int temp = this->m_ptr_stack[child];
this->m_ptr_stack[child] = this->m_ptr_stack[parent];
this->m_ptr_stack[parent] = temp;
}
adjust_sort(2 * parent);
adjust_sort(2 * parent + 1);//sort是从上往下实现,先序
}
}
void test01() {
Maxheap st1(100);
st1.create_heap(9);
st1.arr_print();
for (int i = 0; i < 9; i++) {
cout << st1.PopMax() << " ";
}
cout << endl;
}
int main() {
test01();
system("pause");
return 0;
}