我想在C ++中实现Max-Heap数据结构。必须动态分配它以尽可能少地占用内存。我为它编写了两个函数,Push和Heapify(基于Cormen的算法简介),但是对于输入1,3,5,7我得到的堆看起来像5; 1; 3; 7(所以7是一个人的儿子,我无法找到我犯错的地方。
int parent(int i) { return (i - 1) / 2; }
int left(int i) { return 2 * i + 1; }
int right(int i) { return 2 * i + 2; }
// Inserting element into heap
void Push(int val) {
int *tmp = new int[size + 1];
int i = 0;
for (i; i < size; i++) tmp[i] = arr[i];
tmp[size] = val; // Insert as leaf
delete[] arr;
arr = new int[size + 1];
arr = tmp;
size++;
Heapify(arr, 0);
}
void Heapify(int *arr, int i) {
int largest, tmp;
int l = left(i);
int r = right(i);
if ((l <= size) && (arr[l] > arr[i])) largest = l;
else largest = i;
if ((r <= size) && (arr[r] > arr[largest])) largest = r;
if (largest != i) {
tmp = arr[i];
arr[i] = arr[largest];
arr[largest] = tmp;
Heapify(arr, largest);
}
}
编辑:这些是Heap类中的方法
答案 0 :(得分:0)
您的代码和算法存在多个问题:
Heapify
方法的作用是维护节点的堆属性,其中左右子树已经是max-heaps,只有节点本身可能违反堆属性。您错误地使用它将密钥插入堆中。您需要使用IncreaseKey
将新密钥插入堆中:
void IncreaseKey(int index, int value) {
arr[index] = value;
int parentIndex;
while(index > 0 && arr[(parentIndex = parent(index))] < arr[index]){
int tmp = arr[parentIndex];
arr[parentIndex] = arr[index];
arr[index] = tmp;
index = parentIndex;
}
}
并且Push
方法变为:
void Push(int val) {
int *tmp = new int[size + 1];
for (int i = 0; i < size; i++)
tmp[i] = arr[i];
delete[] arr;
arr = tmp;
size++;
IncreaseKey(size-1, val);
}
在Heapify
方法中,您有以下条件:
if ((l <= size) && ...
和
if ((r <= size) && ...
<=
应更改为<
,因为您在致电size
之前已增加Heapify
。
您的代码中还存在其他问题:
最好更改一下:
int i = 0;
for (i; i < size; i++) tmp[i] = arr[i];
到此(#1):
for (int i; i < size; i++) tmp[i] = arr[i];
或者这个(但上面的代码仍然更好,因为它限制了i
到for
语句的范围)(#2):
int i = 0;
for (; i < size; i++) tmp[i] = arr[i];
它们之间没有功能差异,但是for
循环的第一部分没有做任何事情,并且在循环之后你也不需要i
。所以#1是最好的。
这些方面存在一个更微妙的问题:
arr = new int[size + 1];
arr = tmp;
您分配了一个内存,并且没有释放它,重新分配了变量,并丢失了已分配内存的地址。 tmp
已经分配给您分配的内存,因此请删除第一行,然后您就可以了。