way:看上去好像就是加了个indexMap记录节点在数组heap中的下标,然后就是可以查到某个元素是否在堆里并且可以进行位置的调整,普通的堆是没法知道元素是不是在的,只能弹堆顶元素,插入到堆尾这样子。如果觉得heapSize有点混淆的话,可以heapSize处理之后再去做操作,不用++,--搞得不明白。知道方法的实现过程就好啦,swap在交换时同步修改indexMap,remove把remove的元素和最后的交换,要remove的元素在最后,再调整在 i 位置处的end元素就可以了。heapInsert和heapify和普通堆相比都多了index参数。
成员: vector<Node *> heap, map<Node *, int> indexMap, int heapSize, comp对象比较函数(我没用,可以根据情况看要不要)。
方法:构造,bool isEmpty,int size,bool contains,Node * top,void push(Node * node),Node * pop,void remove(Node * node),void resign(Node *node),void heapInsert(int index),void heapify(int index),void swap(int i, int j),vector<Node *> getAllElements。
#include<iostream>
#include<vector>
#include<map>
using namespace std;typedef int T;struct Node
{T val;Node(T val){this->val = val;}
};//这回不限制大小了哈哈哈
class MyMaxHeap
{
private:vector<Node*>heap;map<Node*, int>indexMap;int heapSize;public:MyMaxHeap(){heapSize=0;}bool isEmpty(){return heapSize==0;}int size(){return heapSize;}bool contains(Node *node){return indexMap.count(node)>0;}Node *top(){if(isEmpty()) return nullptr;return heap[0];}void push(Node *node){heap.push_back(node);heapSize++;indexMap[node]= heapSize-1;heapInsert(heapSize-1);}//这个swap函数在交换的同时把indexMap也悄悄的交换了void swap(int i, int j){Node *a = heap[i];Node *b = heap[j];indexMap[a]=j;indexMap[b]=i;heap[i]=b;heap[j]=a;}void heapInsert(int index){//从index位置开始向上浮动int fa = (index-1)/2;while(heap[index]->val > heap[fa]->val){swap(index, fa);index = fa;fa = (index-1)/2;}}Node *pop(){//要删除堆顶的元素Node *del = heap[0];//最后一个元素//Node *end = heap[heapSize-1];//交换之后要删除的数在堆尾,堆尾的元素在0位置处待处理swap(0, heapSize-1);//先处理要删除的元素heap.pop_back();indexMap.erase(del);heapSize--;//再处理在0位置的元素heapify(0);return del;}void heapify(int index){int left = 2*index+1;//从index位置开始往下沉while(left < heapSize){int maxChild = (left+1<heapSize && heap[left+1]->val > heap[left]->val)? left+1:left;if(heap[index]->val > heap[maxChild]->val){break;}swap(index, maxChild);index = maxChild;left = 2*index+1;}}void remove(Node *node){Node *end = heap[heapSize-1];int i = indexMap[node];//交换要移除的元素和最后一个元素的位置swap(i, heapSize-1);//此时要移除的元素在最后,最后一个元素在i位置上//处理要移除的元素heap.pop_back();indexMap.erase(node);heapSize--;//处理在i位置上的元素resign(end);}void resign(Node *node){int index = indexMap[node];//可能往上浮heapInsert(index);//也可能往下沉heapify(index);}vector<Node *>getAllElements(){return heap;}
};int main()
{MyMaxHeap heap;vector<Node*>nodes;nodes.push_back(new Node(1));nodes.push_back(new Node(2));nodes.push_back(new Node(3));nodes.push_back(new Node(4));nodes.push_back(new Node(5));nodes.push_back(new Node(6));for(auto node:nodes){heap.push(node);}cout<<"堆顶元素是"<<endl;cout<<heap.top()->val<<endl;cout<<"移除元素6"<<endl;heap.remove(nodes[5]);cout<<"堆顶元素是"<<endl;cout<<heap.top()->val<<endl;cout<<"移除元素5"<<endl;heap.remove(nodes[4]);cout<<"堆顶元素是"<<endl;cout<<heap.top()->val<<endl;system("pause");return 0;
}
可以和普通大根堆对比着看实现过程。手写堆(大根堆)-CSDN博客