C++ 二叉堆
二叉堆是一个完全二叉树
二叉堆元素插入:1,往数组尾部插入一个元素。2,对插入的元素,比较他在树形结构中,和他的父节点的大小关系,来决定是否和父节点进行交换
二叉堆获取堆顶元素:返回数组的第0个元素,时间复杂度为o(1)
二叉堆删除元素:1,把数组的第0个元素和最后一个元素交换。2,删除数组的最后一个元素。3,对堆顶元素做下沉操作直到再次满足堆的性质。
二叉堆模版代码,代码见下:
#include<iostream>
using namespace std;// priority_queue
#define maxn 100010
#define lson(idx) (2*idx+1)
#define rson(idx) (2*idx+2)
#define parent(idx) ((idx-1)/2)template<typename T>
struct Small {bool operator()(const T& left, const T& right) const {return left < right;}
};template<typename T>
struct Big {bool operator()(const T& left, const T& right) const {return left > right;}
};template<class T, typename cmp>
class Heap {
private:void shiftUp(int curr);void shiftDown(int curr);public:Heap(int cap = maxn);~Heap();void push(const T& data);void pop();T top() const;bool empty() const;void clear() const;private:T* m_data;int m_size;int m_capacity;cmp m_cmp;
};template<class T, typename cmp>
void Heap<T, cmp>::shiftUp(int curr)
{if (curr == 0) {return;}int par = parent(curr);if (m_cmp(m_data[curr], m_data[par])) {swap(m_data[curr], m_data[par]);shiftUp(par);}
}template<class T, typename cmp>
void Heap<T, cmp>::shiftDown(int curr)
{int lsonId = lson(curr);int rsonId = rson(curr);int optId = curr;if (lsonId < m_size && m_cmp(m_data[lsonId], m_data[optId])){optId = lsonId;}if (rsonId < m_size && m_cmp(m_data[rsonId], m_data[optId])) {optId = rsonId;}if (optId != curr) {swap(m_data[curr], m_data[optId]);shiftDown(optId);}}template<class T, typename cmp>
Heap<T, cmp>::Heap(int cap)
{m_data = new T[cap];m_capacity = cap;m_size = 0;
}template<class T, typename cmp>
Heap<T, cmp>::~Heap()
{delete[] m_data;m_data = NULL;
}template<class T, typename cmp>
void Heap<T, cmp>::push(const T& data)
{m_data[m_size++] = data;shiftUp(m_size - 1);
}template<class T, typename cmp>
void Heap<T, cmp>::pop()
{swap(m_data[0], m_data[m_size - 1]);--m_size;shiftDown(0);
}template<class T, typename cmp>
T Heap<T, cmp>::top() const
{return m_data[0];
}template<class T, typename cmp>
bool Heap<T, cmp>::empty() const
{return m_size == 0;
}template<class T, typename cmp>
void Heap<T, cmp>::clear() const
{m_size = 0;
}int main() {Heap<int, Big<int>> q;for (int i = 0; i < 5; ++i) {int x = rand() % 30, y = rand() % 30;q.push(x);q.push(y);cout << "塞入两个数:" << x << ' ' << y << endl;cout << "目前最大的数是:" << q.top() << endl;q.pop();cout << "弹出最大的那个数" << endl;}}代码练习 1 对应蓝桥云课 小蓝的最大集合 代码见下
#include<iostream>
using namespace std;// priority_queue
#define maxn 200010
#define lson(idx) (2*idx+1)
#define rson(idx) (2*idx+2)
#define parent(idx) ((idx-1)/2)template<typename T>
struct Small {bool operator()(const T& left, const T& right) const {return left < right;}
};template<typename T>
struct Big {bool operator()(const T& left, const T& right) const {return left > right;}
};template<class T, typename cmp>
class Heap {
private:void shiftUp(int curr);void shiftDown(int curr);public:Heap(int cap = maxn);~Heap();void push(const T& data);void pop();T top() const;bool empty() const;void clear() const;private:T* m_data;int m_size;int m_capacity;cmp m_cmp;
};template<class T, typename cmp>
void Heap<T, cmp>::shiftUp(int curr)
{if (curr == 0) {return;}int par = parent(curr);if (m_cmp(m_data[curr], m_data[par])) {swap(m_data[curr], m_data[par]);shiftUp(par);}
}template<class T, typename cmp>
void Heap<T, cmp>::shiftDown(int curr)
{int lsonId = lson(curr);int rsonId = rson(curr);int optId = curr;if (lsonId < m_size && m_cmp(m_data[lsonId], m_data[optId])){optId = lsonId;}if (rsonId < m_size && m_cmp(m_data[rsonId], m_data[optId])) {optId = rsonId;}if (optId != curr) {swap(m_data[curr], m_data[optId]);shiftDown(optId);}}template<class T, typename cmp>
Heap<T, cmp>::Heap(int cap)
{m_data = new T[cap];m_capacity = cap;m_size = 0;
}template<class T, typename cmp>
Heap<T, cmp>::~Heap()
{delete[] m_data;m_data = NULL;
}template<class T, typename cmp>
void Heap<T, cmp>::push(const T& data)
{m_data[m_size++] = data;shiftUp(m_size - 1);
}template<class T, typename cmp>
void Heap<T, cmp>::pop()
{swap(m_data[0], m_data[m_size - 1]);--m_size;shiftDown(0);
}template<class T, typename cmp>
T Heap<T, cmp>::top() const
{return m_data[0];
}template<class T, typename cmp>
bool Heap<T, cmp>::empty() const
{return m_size == 0;
}template<class T, typename cmp>
void Heap<T, cmp>::clear() const
{m_size = 0;
}int main(){Heap<int, Big<int>> q;int n, k;int sum = 0;cin >> n >> k;q.push(k);while(n--){int a;cin >> a;if(a == 4){cout << q.top() + sum << endl;q.pop();}else{int x;cin >> x;if(a == 1){q.push(x - sum);}else if(a == 2){sum += x;}else if(a == 3){sum -= x;}}}}代码 2 对应蓝桥云课 第k大的数,代码见下
#include<iostream>
using namespace std;// priority_queue
#define maxn 200010
#define lson(idx) (2*idx+1)
#define rson(idx) (2*idx+2)
#define parent(idx) ((idx-1)/2)template<typename T>
struct Small {bool operator()(const T& left, const T& right) const {return left < right;}
};template<typename T>
struct Big {bool operator()(const T& left, const T& right) const {return left > right;}
};template<class T, typename cmp>
class Heap {
private:void shiftUp(int curr);void shiftDown(int curr);public:Heap(int cap = maxn);~Heap();void push(const T& data);void pop();T top() const;bool empty() const;void clear() const;private:T* m_data;int m_size;int m_capacity;cmp m_cmp;
};template<class T, typename cmp>
void Heap<T, cmp>::shiftUp(int curr)
{if (curr == 0) {return;}int par = parent(curr);if (m_cmp(m_data[curr], m_data[par])) {swap(m_data[curr], m_data[par]);shiftUp(par);}
}template<class T, typename cmp>
void Heap<T, cmp>::shiftDown(int curr)
{int lsonId = lson(curr);int rsonId = rson(curr);int optId = curr;if (lsonId < m_size && m_cmp(m_data[lsonId], m_data[optId])){optId = lsonId;}if (rsonId < m_size && m_cmp(m_data[rsonId], m_data[optId])) {optId = rsonId;}if (optId != curr) {swap(m_data[curr], m_data[optId]);shiftDown(optId);}}template<class T, typename cmp>
Heap<T, cmp>::Heap(int cap)
{m_data = new T[cap];m_capacity = cap;m_size = 0;
}template<class T, typename cmp>
Heap<T, cmp>::~Heap()
{delete[] m_data;m_data = NULL;
}template<class T, typename cmp>
void Heap<T, cmp>::push(const T& data)
{m_data[m_size++] = data;shiftUp(m_size - 1);
}template<class T, typename cmp>
void Heap<T, cmp>::pop()
{swap(m_data[0], m_data[m_size - 1]);--m_size;shiftDown(0);
}template<class T, typename cmp>
T Heap<T, cmp>::top() const
{return m_data[0];
}template<class T, typename cmp>
bool Heap<T, cmp>::empty() const
{return m_size == 0;
}template<class T, typename cmp>
void Heap<T, cmp>::clear() const
{m_size = 0;
}int main()
{Heap<int, Small<int>> q;int n, k;cin >> n >> k;for(int i=0; i<n; ++i){int x;cin >> x;q.push(x);}for(int i=0; i<k; ++i){int x;cin >> x;if(x > q.top()){q.push(x);q.pop();}cout << q.top() << " ";}cout << endl;// 请在此输入您的代码return 0;
}代码练习 3 对应蓝桥云课 一道简单的取模问题 代码见下
#include<iostream>
using namespace std;// priority_queue
#define maxn 200010
#define lson(idx) (2*idx+1)
#define rson(idx) (2*idx+2)
#define parent(idx) ((idx-1)/2)template<typename T>
struct Small {bool operator()(const T& left, const T& right) const {return left < right;}
};template<typename T>
struct Big {bool operator()(const T& left, const T& right) const {return left > right;}
};template<class T, typename cmp>
class Heap {
private:void shiftUp(int curr);void shiftDown(int curr);public:Heap(int cap = maxn);~Heap();void push(const T& data);void pop();T top() const;bool empty() const;void clear() const;private:T* m_data;int m_size;int m_capacity;cmp m_cmp;
};template<class T, typename cmp>
void Heap<T, cmp>::shiftUp(int curr)
{if (curr == 0) {return;}int par = parent(curr);if (m_cmp(m_data[curr], m_data[par])) {swap(m_data[curr], m_data[par]);shiftUp(par);}
}template<class T, typename cmp>
void Heap<T, cmp>::shiftDown(int curr)
{int lsonId = lson(curr);int rsonId = rson(curr);int optId = curr;if (lsonId < m_size && m_cmp(m_data[lsonId], m_data[optId])){optId = lsonId;}if (rsonId < m_size && m_cmp(m_data[rsonId], m_data[optId])) {optId = rsonId;}if (optId != curr) {swap(m_data[curr], m_data[optId]);shiftDown(optId);}}template<class T, typename cmp>
Heap<T, cmp>::Heap(int cap)
{m_data = new T[cap];m_capacity = cap;m_size = 0;
}template<class T, typename cmp>
Heap<T, cmp>::~Heap()
{delete[] m_data;m_data = NULL;
}template<class T, typename cmp>
void Heap<T, cmp>::push(const T& data)
{m_data[m_size++] = data;shiftUp(m_size - 1);
}template<class T, typename cmp>
void Heap<T, cmp>::pop()
{swap(m_data[0], m_data[m_size - 1]);--m_size;shiftDown(0);
}template<class T, typename cmp>
T Heap<T, cmp>::top() const
{return m_data[0];
}template<class T, typename cmp>
bool Heap<T, cmp>::empty() const
{return m_size == 0;
}template<class T, typename cmp>
void Heap<T, cmp>::clear() const
{m_size = 0;
}int main()
{Heap<int, Big<int>> q;int n, k;long long sum = 0;cin >> n >> k;for(int i=0; i<n; ++i){int x;cin >> x;q.push(x);sum += x;}while(k--){int x;cin >> x;while(!q.empty()){if(q.top() >= x){sum -= q.top();int y = q.top() % x;sum += y;q.pop();q.push(y);}else break;}cout << sum << " ";}cout << endl;// 请在此输入您的代码return 0;
}