前言
在写leetcode
的时候,看到一道优先队列的题目,复习了一下最大堆,用c++
实现了一下。以前听网课的时候,根本看不懂实现,现在自己也能实现了。
参考文献
这个我觉得讲得挺好的,图很生动形象
代码
#include<iostream>
#include<vector>class MaxHeap {
public:MaxHeap(std::vector<int>& nums); // 用一个数组建立最大堆int top(); // 取出堆顶元素void pop(); // 删除堆顶元素void insert(int num); // 插入元素void print(){for (int i = 1; i < this->_nums.size(); ++i){std::cout << this->_nums[i] << " ";}std::cout << std::endl;}private:std::vector<int> _nums; // 最大堆数组
};int main()
{std::vector<int> nums2;MaxHeap b(nums2); 测试异常// 正常情况std::vector<int> nums{ 1,2,3,4,5 };MaxHeap aHeap(nums);aHeap.print();//std::cout << aHeap.top() << std::endl;aHeap.pop();aHeap.print();aHeap.insert(6);aHeap.print();return 0;
}MaxHeap::MaxHeap(std::vector<int>& nums)
{int cnt = nums.size();if (cnt < 1){std::cout << "vector param must has at least one element." << std::endl;return;}this->_nums.assign(cnt + 1, 0); // 开辟cnt+1个空间for (int i = 1; i <= cnt; ++i){this->_nums[i] = nums[i-1];// 和它的父节点比较int father_index = i / 2;int cur_position = i; // 它的当前位置while (father_index > 0) // 一直交换到它小于它的父节点{if (this->_nums[cur_position] > this->_nums[father_index]){// 交换int tmp = this->_nums[father_index];this->_nums[father_index] = this->_nums[cur_position];this->_nums[cur_position] = tmp;cur_position = father_index; // 更新它的当前位置father_index /= 2; // 更新父节点}else break;}}
}int MaxHeap::top()
{if (this->_nums.size() == 0) {std::cout << "heap's size == 0, unleagal operation." << std::endl;return 0;}return this->_nums[1];
}void MaxHeap::pop()
{if (this->_nums.size() == 0) {std::cout << "heap's size == 0, unleagal operation." << std::endl;return;}// 堆顶元素移除, 重新恢复最大堆// 将最后一个元素放到堆顶int size = this->_nums.size();this->_nums[1] = this->_nums[size - 1];size = size - 1;this->_nums.resize(size);int cur_position = 1; // 记录当前位置int son_max_value; // 孩子的最大值while (cur_position < size - 1) {if (cur_position * 2 <= size - 1){int son_max_value_index = cur_position * 2;// 左孩子存在son_max_value = this->_nums[cur_position * 2];if (cur_position * 2 + 1 < size - 1){// 右孩子存在son_max_value = son_max_value > this->_nums[cur_position * 2 + 1] ? son_max_value : this->_nums[cur_position * 2 + 1];if (son_max_value == this->_nums[cur_position * 2 + 1]){son_max_value_index += 1;}}//std::cout << cur_position << std::endl;if (this->_nums[cur_position] < son_max_value){// 交换int tmp = this->_nums[son_max_value_index];this->_nums[son_max_value_index] = this->_nums[cur_position];this->_nums[cur_position] = tmp;cur_position = son_max_value_index;}else {//std::cout << cur_position << std::endl;break;}}else break;}
}void MaxHeap::insert(int num)
{if (this->_nums.size() == 0) {std::cout << "heap's size == 0, unleagal operation." << std::endl;return;}// 在最后面插入元素this->_nums.push_back(num);// 然后将它调成最大堆int cur_position = this->_nums.size()-1;int father_index = cur_position / 2;int father_index_value;while (father_index > 0) // 只要没有到堆顶就有一直比较的可能{father_index_value = this->_nums[father_index];if (father_index_value < num) {// 交换 this->_nums[father_index] = num;this->_nums[cur_position] = father_index_value;cur_position = father_index;father_index = cur_position / 2;}else break;}
}