昔、「二分木は配列で実装できます。」みたいなことを読んだことがありました。
そのときは、??だったが、今ならできる!!
では、早速ソースを。
class myHeap {
public:
myHeap() {
this->tail = 0;
}
void add(int n) {
hp[tail++] = n;
int pos = tail-1;
while (pos) {
if (hp[(pos-1)/2] < hp[pos])
swap(hp[(pos-1)/2], hp[pos]);
pos = (pos-1)/2;
}
}
int pop() {
if (isEmpty()) {
cerr << "Heap is empty!" << endl;
return -1;
}
int ret = hp[0];
hp[0] = hp[--tail];
int pos = 0;
while (2 * pos + 2 <= tail) {
if (hp[pos] > max(hp[2*pos+1], hp[2*pos+2]))
break;
if (hp[2*pos+1] > hp[2*pos+2]) {
swap(hp[pos], hp[2*pos+1]);
pos = 2*pos+1;
}
else {
swap(hp[pos], hp[2*pos+2]);
pos = 2*pos+2;
}
}
return ret;
}
bool isEmpty() {
return tail <= 0;
}
private:
int hp[1<<10];
int tail;
};
で、ちゃんと動くか確認してみましょう。
int main() {
myHeap hp = myHeap();
REP(i, 100)
hp.add(rand() % 1000);
while (!hp.isEmpty())
printf("%d\n", hp.pop());
return 0;
}
はい、動きました。
実際に自分で作ってみると、ヒープのオーダーについての理解も深まります。
- 最大値の参照は、O(1)
- push()およびpop()は、O(log n)
なのは明らかですね。
0 件のコメント:
コメントを投稿