-
数据结构堆的介绍:堆与堆排序
-
用于作业调度的最大/小优先队列可以使用堆来实现:
• 最大优先队列支持以下操作
○ INSERT(S, x):把元素x插入集合S
○ MAXIMUM(S):返回S中具有最大关键字的元素
○ EXTRACT-MAX(S):去掉并返回S中的具有最大键字的元素
○ INCERASE-KEY(S, x, k):将元素x的关键字值增加到k,这里假设k的值不小于x的原关键字值• 最小优先队列支持以下操作:
○ INSERT
○ MINIMUM
○ EXTRACT_MIN
○ DECREASE_KEY -
最小优先队列的C++实现:
class MinHeapFirstQueue { public: MinHeapFirstQueue() {}; ~MinHeapFirstQueue() {}; void insert(int id); //插入元素 int minimum(); //返回最小关键字的元素 int extract_min(); //去掉并返回最小关键字的元素 void decrease_key(int id, int k); //把元素id的关键字减少到k,k不小于原关键字 private: int parent_(int idx); int left_(int idx); int right_(int idx); bool shit_down_(int id, int size); //降级,不能降级返回false void shit_up_(int id); void swap_(int id1, int id2); void del_(int id); std::vector<int> keys_; std::unordered_map<int, int> dx_map_; //id-idx map std::unordered_map<int, int> xd_map_; //idx-id map }; void MinHeapFirstQueue::insert(int id) { if(id < 0) { return; } if(dx_map_.count(id) == 0) //插入新的元素 { cout << "new node" << endl; dx_map_[id] = keys_.size(); xd_map_[keys_.size()] = id; keys_.push_back(0); //初始的关键值设为0 shit_up_(id); } else { cout << "insert existing node" << endl; keys_[dx_map_[id]] = 0; if(!shit_down_(id, keys_.size())) { shit_up_(id); } } return ; } int MinHeapFirstQueue::minimum() { if(keys_.empty()) { cout << "队列为空!" << endl; return (1 << 30) - 1; } return keys_[0]; } int MinHeapFirstQueue::extract_min() { int ret = 0; if(keys_.empty()) { cout << "extract_min: 优先队列为空!" << endl; return -1; } ret = keys_[0]; del_(xd_map_[0]); return ret; } void MinHeapFirstQueue::decrease_key(int id, int k) { if(dx_map_.count(id) == 0) { return ; } if(keys_[dx_map_[id]] < k) { return ; } keys_[dx_map_[id]] = k; shit_up_(id); } inline int MinHeapFirstQueue::parent_(int idx) { return (idx - 1) / 2; } inline int MinHeapFirstQueue::left_(int idx) { return 2 * idx + 1; } inline int MinHeapFirstQueue::right_(int idx) { return 2 * idx + 2; } bool MinHeapFirstQueue::shit_down_(int id, int size) { int i = dx_map_[id]; int j = left_(i); while(j < size) //迭代实现 { if(right_(i) < size && keys_[right_(i)] < keys_[j]) { j = right_(i); } if(keys_[i] < keys_[j]) { break; } swap_(xd_map_[i], xd_map_[j]); i = j; j = left_(i); } return dx_map_[id] > xd_map_[i]; } void MinHeapFirstQueue::shit_up_(int id) { int i = dx_map_[id]; int j = parent_(i); if(i == 0) { cout << "shit_up: root node" << endl; return; } cout << "shitup: j: " << j << endl; while(j >= 0) { if(keys_[i] > keys_[j]) { break; } swap_(xd_map_[i], xd_map_[j]); i = j; if(i == 0) { cout << "shit_up: root node" << endl; return; } j = parent_(i); } } void MinHeapFirstQueue::swap_(int id1, int id2) { int idx1 = 0; int idx2 = 0; if(dx_map_.count(id1) == 0 || dx_map_.count(id2) == 0) { return ; } idx1 = dx_map_[id1]; idx2 = dx_map_[id2]; std::swap(keys_[idx1], keys_[idx2]); dx_map_[id1] = idx2; dx_map_[id2] = idx1; xd_map_[idx1] = id2; xd_map_[idx2] = id1; } void MinHeapFirstQueue::del_(int id) { int i = 0; int j = 0; if(dx_map_.count(id) == 0) { return ; } i = dx_map_[id]; j = keys_.size() - 1; if(i < j) //非队尾元素 { swap_(xd_map_[i], xd_map_[j]); //把删除的元素移到队尾 if(!shit_down_(xd_map_[i], keys_.size()-1)) //维护堆的性质 { shit_up_(xd_map_[i]); } } dx_map_.erase(xd_map_[j]); xd_map_.erase(j); keys_.pop_back(); } int main() { MinHeapFirstQueue fq; fq.insert(0); fq.insert(1); fq.insert(2); fq.decrease_key(0, -1); cout << fq.minimum() << endl; fq.decrease_key(1, -2); cout << fq.minimum() << endl; fq.decrease_key(2, -3); cout << fq.minimum() << endl; cout << fq.extract_min() << endl; cout << fq.minimum() << endl; cout << fq.extract_min() << endl; cout << fq.minimum() << endl; cout << fq.extract_min() << endl; cout << fq.minimum() << endl; return 0; }```
堆——最小优先队列以及实现
最新推荐文章于 2022-03-29 08:49:14 发布
![](https://img-home.csdnimg.cn/images/20240711042549.png)