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博客