ヒープが配列に基づいており、ルートが抽出されている場合、私が使用しているコードは、ヒープ プロパティが維持されるようにノードを再シャッフルすることを想定しています。
私の理解では、配列とヒープはまったく同じではありませんが、コードでは、ヒープを構築することは、ヒープ プロパティを保持するように配列を再配置するだけのようです。これはヒープを作成する標準的な方法ですか? ベースとなる配列を変更するだけでなく、別の配列を埋める必要がありますか?
function を使用してルートを削除するとextract-max
、配列から要素をポップしない限り、配列は同じサイズのままであるため、この概念を理解するのに苦労しています。ヒープは小さいはずですが、ルートを置き換えるために上に移動したノードが配列内でゼロで示され、削除されないだけです。
ヒープが基本的にヒープ プロパティに従う配列である構造を保持する場合、ヒープの一部ではなくなったノードを削除するにはどうすればよいですか? 私のコードでは、このノードは0
、配列を印刷するときに a で示されます。
#include <iostream>
#include <deque>
#include "print.h"
#include "random.h"
int parent(int i)
{
return (i - 1) / 2;
}
int left(int i)
{
if(i == 0)
return 1;
else
return 2*i;
}
int right(int i)
{
if(i == 0)
return 2;
else
return 2*i + 1;
}
void max_heapify(std::deque<int> &A, int i, int heapsize)
{
int largest;
int l = left(i);
int r = right(i);
if(l <= heapsize && A[l] > A[i])
largest = l;
else
largest = i;
if(r <= heapsize && A[r] > A[largest])
largest = r;
if(largest != i) {
exchange(A, i, largest);
max_heapify(A, largest, heapsize);
}
}
void build_max_heap(std::deque<int> &A)
{
int heapsize = A.size() - 1;
for(int i = (A.size() - 1) / 2; i >= 0; i--)
max_heapify(A, i, heapsize);
}
int heap_extract_max(std::deque<int> &A, int heapsize)
{
if(heapsize < 0)
throw std::out_of_range("heap underflow");
int max = A.front();
//A.pop_front();
A[0] = A[heapsize--];
//A.pop_back();
max_heapify(A, 0, heapsize);
return max;
}
int main(int argc, const char * argv[])
{
std::deque<int> B = deq(7);
print(B);
build_max_heap(B);
print(B);
std::cout << "Extract max ->\t" << heap_extract_max(B, B.size()) << std::endl;
print(B);
std::cout << "Extract max ->\t" << heap_extract_max(B, B.size()) << std::endl;
print(B);
return 0;
}
出力:
79 92 86 29 27 42 6
92 86 79 29 27 42 6
Extract max -> 92
86 79 42 29 27 0 6
Extract max -> 86
79 42 27 29 0 0 6