本文主要是介绍【C++】大顶堆(最大堆)手工模拟优先队列,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
前言
本文采用结构体重载比较运算符的方式进行大根堆的建立,算法逻辑类似 S T L STL STL的 p r i o r i t y _ q u e u e priority\_queue priority_queue。
结构体
堆本身就是一颗完全二叉树,所以本身用数组存储就行。
int heap[N];
输入堆
for(int i=1;i<=n;i++} cin>>heap[i];
向上调整堆
建堆后,从第一个非叶结点开始向前递减循环,依次比较堆是否比最大的孩子小,是的话则交换。
void adjustUp(){for(int i=len/2;i>=1;i--){int l=2*i;//默认左孩子if(l+1<=len&&heap[l+1]>heap[l] l++;//最大为右孩子情况if(heap[m]>heap[i] swap(heap[m],heap[i];//交换m,i}
}
删除堆顶元素
在堆中,删除堆顶元素实际上就是交换堆顶和最后一个元素后让堆长度减 1 1 1。然后从堆顶 i = 1 i=1 i=1开始向下调整:
- 找到 i i i最大的孩子结点编号 i c ic ic
- 比较 i i i与 i c ic ic值的大小,若不符合堆得定义则交换
- 令 i = i c i=ic i=ic,继续第1步直到 i i i为叶子结点
void deleteHeap(){//交换堆顶和尾部元素cout<<heap[1]<<' ';swap(heap[1],heap[len]);len--;//长度-1int i=1;//分支选择iwhile(2*i<=len){int j=2*i+1;//进入下一层if(j>len || heap[j-1]>heap[j]) j--;if(heap[i]<heap[j] swap(heap[i],heap[j]);i=j;}
}
优先队列方式输出
有输入当然也有输出
void input(){while(len!=0){deleteHeap();}
}
STL堆
在STL库当中,自然也是有堆的相关函数的,位于 < a l g o r i t h m > <algorithm> <algorithm>。- heap没有对应容器,STL中只有相关算法:
-
make_heap 建堆
-
push_heap 入堆
-
pop_heap 出堆
-
sort_heap 排序堆
他们的参数如下所示:
void make_heap(first,last,comp)
void push_heap(first,last,comp)
void pop_heap(first,last,comp)
void sort_heap(first,last,comp)
各含义如下:
first 堆起始位置 num+i s.begin()
last 堆末尾位置+1 num+n s.end()
comp 自定义比较函数,不填默认大顶堆
除了push_heap,全都是[first,last)
push_heap将last加入堆[first,last-1)
入堆
入堆很简单,输入数组第i个后,直接采取区间的方式调用函数即可。
cin>>n;//入堆n个元素
for(int i=0;i<n;i++){int p;cin>>num[i]; push_heap(num,num+i);//入堆
}
出堆
出堆的话,因为大小一直在改变,所以循环要逆序,堆顶是数组 0 0 0的位置,每次输出后要调用 p o p h e a p pop_heap popheap重新调整堆。
for(int i=n+1;i>=0;i--){//输出之后排堆的元素少1 cout<<num[0]<<' ';pop_heap(num,num+i);//出堆
}
这篇关于【C++】大顶堆(最大堆)手工模拟优先队列的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!