公共函數:
比較大小:
private boolean less(Array pq, int i ,int j){
return pq[i].compareTo(pq[j]) < 0 ;
}
交換:
private void exch(Array pq , int i , int j ){
Key t = pq[i] ;
pq[i] = pq[j] ;
pq[j] = t ;
}
上浮: 當兒大於父,將兒不斷向上交換。初始化時一般從N/2位置開始
private void swim(Array pq ,int k){
while( k>1 && less( k/2, k)){
exch(pq , k/2 , k);
}
}
下沉: 當父小於兒,將父不斷向下。初始化時一般從1開始
private void sink(Array pq , int k){
while (2*k <= N){ //N是pq.length
int j = 2*k;
if(j < N && less(j , j+1)) j++;
if(!less(pq , k , j)) break;
exch(pq , k , j);
k = j;
}
}
概念:
每個節點都大於其子節點,這是堆的特性。所以當初始堆不符合這樣的特點時候,就需要進行堆的初始化。
堆的初始化:
1)堆初始化主要是滿足每個父節點大於等於子節點,而葉節點根本沒有子節點,所以不考慮葉節點
2)因爲不需要考慮葉節點,所以N/2位置一般爲截斷點
3)遇到不符合特點的節點,通過sink或者swim函數來調整
public void init(){
int N = a.length;
for(int k = 1;k <= N/2;k++){
sink(a , k)
}
}
1)把新增的節點放到最後
2)節點上浮到相應位置即可
public void insert (Array pq , Key v) {
int N = pq.length;
pq[++N] = v;
swim(pq , N);
}
堆的刪除:
1)把要刪除的元素與最後葉節點交換位置
2)被交換的葉節點進行下沉操作
3)把要刪除的元素爲null
public void del(int d , Array pq){
Key del = pq[d];
int N = pq.length;
exch(pq , d , N--); // 交換最後葉節點與要刪除元素位置
sink(pq , d); //下沉操作
pq[N+1] = null; //要刪除元素置null
}
堆的排序:
1)根節點與葉節點互換
2)下沉操作
3)原根節點刪除並存入新數組中
4)重複上面操作
while (N > 1) {
exch(pq , 1 ,N--) ; // 交換根和最大葉節點位置
sink(pq , 1); // 現在根節點下沉操作
}