ヒープのshift up
本節では、最大ヒープに要素を追加する方法を紹介します。これをshift up。
下の最大ヒープに新しい要素52を追加し、配列の最後の位置に置くとします。52は親ノード16より大きいため、この時点でヒープの定義を満たしておらず、調整が必要です。

まず、インデックス5と11の配列内の数値の位置を交換します。つまり、52と16の位置を交換します。

この時、52は依然として親ノードのインデックス2の値41より大きいため、さらに位置を移動する必要があります。

ここで52と62の大小を比較すると、52はすでに親ノードより小さいため、これ以上上昇させる必要はなく、最大ヒープの定義を満たしています。このプロセスを最大ヒープのshift upと呼びます。
Java インスタンスコード
ソースコードパッケージのダウンロード:Download
src/サンプル/heap/HeapShiftUp.java ファイルコード:
package サンプル.heap;
/**
* ヒープに要素を追加する
*/
public class HeapShiftUp<T extends Comparable> {
protected T[] data;
protected int count;
protected int capacity;
// コンストラクタ。capacity個の要素を格納できる空のヒープを構築する
public HeapShiftUp(int capacity){
data = (T[])new Comparable[capacity+1];
count = 0;
this.capacity = capacity;
}
// ヒープ内の要素数を返す
public int size(){
return count;
}
// ヒープが空かどうかを示すブール値を返す
public boolean isEmpty(){
return count == 0;
}
// 最大ヒープに新しい要素 item を挿入する
public void insert(T item){
assert count + 1 <= capacity;
data[count+1] = item;
count ++;
shiftUp(count);
}
// ヒープ内のインデックスiとjの2つの要素を交換する
private void swap(int i, int j){
T t = data[i];
data[i] = data[j];
data[j] = t;
}
//********************
//* 最大ヒープの核心的な補助関数
//********************
private void shiftUp(int k){
while( k > 1 && data[k/2].compareTo(data[k]) < 0 ){
swap(k, k/2);
k /= 2;
}
}
// HeapShiftUp をテストする
public static void main(String[] args) {
HeapShiftUp<Integer> heapShiftUp = new HeapShiftUp<Integer>(100);
int N = 50; // ヒープ内の要素数
int M = 100; // ヒープ内の要素の値の範囲は[0, M)
for( int i = 0 ; i < N ; i ++ )
heapShiftUp.insert( new Integer((int)(Math.random() * M)) );
System.out.println(heapShiftUp.size());
}
}
/**
* ヒープに要素を追加する
*/
public class HeapShiftUp<T extends Comparable> {
protected T[] data;
protected int count;
protected int capacity;
// コンストラクタ。capacity個の要素を格納できる空のヒープを構築する
public HeapShiftUp(int capacity){
data = (T[])new Comparable[capacity+1];
count = 0;
this.capacity = capacity;
}
// ヒープ内の要素数を返す
public int size(){
return count;
}
// ヒープが空かどうかを示すブール値を返す
public boolean isEmpty(){
return count == 0;
}
// 最大ヒープに新しい要素 item を挿入する
public void insert(T item){
assert count + 1 <= capacity;
data[count+1] = item;
count ++;
shiftUp(count);
}
// ヒープ内のインデックスiとjの2つの要素を交換する
private void swap(int i, int j){
T t = data[i];
data[i] = data[j];
data[j] = t;
}
//********************
//* 最大ヒープの核心的な補助関数
//********************
private void shiftUp(int k){
while( k > 1 && data[k/2].compareTo(data[k]) < 0 ){
swap(k, k/2);
k /= 2;
}
}
// HeapShiftUp をテストする
public static void main(String[] args) {
HeapShiftUp<Integer> heapShiftUp = new HeapShiftUp<Integer>(100);
int N = 50; // ヒープ内の要素数
int M = 100; // ヒープ内の要素の値の範囲は[0, M)
for( int i = 0 ; i < N ; i ++ )
heapShiftUp.insert( new Integer((int)(Math.random() * M)) );
System.out.println(heapShiftUp.size());
}
}