优先队列-堆
定义:堆是一种特殊的完全二叉树,(最小堆:所有父节点都比子节点小), 完全二叉树指除最右位置上有一个或多个叶节点缺少外,其他都是丰满的;可以使用数组存储;
堆两个重要操作:shiftdown,shiftup; 【堆顶元素编号为1,父子节点编号关系:父节点i, 左孩子i*2, 右孩子i*2+1】
void shiftdown(int i){ //需要向下调整节点编号i int t,flag=0; //flag用来标记是否需要继续 //至少有左儿子 while(i*2<=n && flag==0){ if(h[i]>h[i*2]){ t=i*2; } if(i*2+1<=n){ if(h[t]>h[i*2+1]){ t=i*2+1; } } if(i!=t){ swap(i,t); i=t; //更新i,便于继续向下调整 }else{ flag=1; //可以结束向下调整 } } } void shiftup(int i){ int flag=0; if(i==1) return; //堆顶,无需调整 while(i!=1 && flag==0){ if(h[i]<h[i/2]){ swap(i,i/2); i=i/2; //更新i为它父节点,便于继续向上调整 }else{ flag=1; } } }
建堆:从最后一个非叶节点(编号n/2)开始到根节点(编号1),逐个根据需要将当前节点向下调整,直到以当前节点为根节点的子树符合堆的特性,时间复杂度 O(N);
void create(){ //从最后一个非叶节点到第一个节点依次进行向下调整 for(int i=n/2;i>1;i--){ shiftdown(i); } }
浙公网安备 33010602011771号