【學習筆記】堆的定義及其建立、排序等基本操作的實現
阿新 • • 發佈:2018-11-12
目錄
詳情請參見《演算法筆記》P335,此處只做簡單的學習筆記記錄。
堆的定義:
堆是一棵完全二叉樹,樹中的每個結點的值都不小於(或不大於)其左右孩子結點。
堆一般用於優先佇列的實現(目前不是很懂),故預設使用的是大頂堆(每個結點的值都大於或等於其左右孩子結點,小於等於時即為小頂堆)。
堆的基本操作的程式碼實現:
堆的定義:因為堆是完全二叉樹,所以可以用陣列存。陣列的下標為1~n,表示第1~n個結點。
const int maxn=100; int heap[maxn],n=10;//heap為堆,n為元素個數
向下調整:O(logn)
void downAdjust(int low,int high)//low為欲調整結點的陣列下標,high一般為堆的最後一個元素的陣列下標 { int i=low,j=i*2;//i為根結點,j為左孩子結點 while(j<=high)//存在孩子結點 { if(j+1<=high && heap[j+1]>heap[j])//存在右孩子且右孩子的值大於左孩子的值 j=j+1;//左右孩子中較大的那個的下標 if(heap[j]>heap[i]) { swap(heap[j],heap[i]); i=j; j=i*2; } else break; } }
建堆:O(n)
void createHeap()//倒序遍歷父親結點
{
for(int i=n/2;i>=1;i--)
downAdjust(i,n);//對父親結點向下調整
}
刪除堆頂元素:O(logn)
void deleteTop()
{
heap[1]=heap[n--];//堆頂元素和最後一個元素交換,且元素個數-1,再對當前的堆頂結點向下調整
downAdjust(1,n);
}
向上調整:O(logn)
void upAdjust(int low,int high)//low一般為1,high一般為預調整結點的陣列下標 { int i=high,j=high/2;//i為孩子結點,j為根結點 while(j>=low)//根結點在[low,high]範圍內 { if(heap[i]>heap[j])//孩子結點的值大於根結點的值 { swap(heap[i],heap[j]); i=j; j=i/2; } else break; } }
新增元素:在堆尾
void insert(int x)
{
heap[++n]=x;
upAdjust(1,n);//向上調整新加入的結點n
}
堆排序:
void heapSort()
{
createHeap();//建堆
for(int i=n;i>1;i--)//直到堆裡只有一個元素時
downAdjust(1,i-1);//調整棧頂,heap[i]此時不算入堆中
}