プログラミングコンテストチャレンジブック(通称”蟻本”)より、色んな項目を詳しく見ていこうと思います。
プログラミングを始めて間もないので、解説は素人です。
2-4「データを工夫して記憶する”データ構造”」
◆ヒープ
…ヒープとは二分木の一種です。
子の数字が親の数字よりも必ず大きいという性質をもちます。
↓実装です。
qiita.c++
//heap[MAX_N]は配列。szはヒープの要素数。
int heap[MAX_N], sz=0;
//void pushはヒープに要素を入れる。
void push(int x){
//自分のノードの番号
int i=sz++;
while(i>0){
//親のノードの番号
int p=(i-1)/2;
//子の数が親の数以上になっていればヒープの条件を満たすので抜ける。
if(heap[p] <=x) break;
//そうでなければ子のノードに親の数字を代入する。
heap[i]=heap[p];
//親のノードに移動する。
i=p;
}
//親のノードにxを代入する。
heap[i]=x;
}
//int popはヒープから要素を取り出す。
int pop(){
//retにヒープの根の数字を代入。
int ret=heap[0];
//xにヒープの最後尾の数を代入。
int x=heap[--sz];
int i=0;
while(i*2+1<sz){
int a=i*2+1,b=i*2+2;
//bが最後尾でないとき、heap[a]とheap[b]の小さい方に着目する。
if(b<sz && heap[b]<heap[a]) a=b;
//heap[a],heap[b]の小さい方がx以上のとき、ヒープの条件を満たすので抜ける。
if(heap[a] >= x) break;
//そうでなければ、i番目にa番目の数字を入れる。
heap[i]=heap[a];
//小さい方の子に移動。
i=a;
}
//ヒープの条件を満たしていれば抜ける。
heap[i]=x;
//根のノードの数字を返す。
return ret;
}