【发布时间】:2020-03-09 13:48:59
【问题描述】:
我正在尝试实现一个基于数组的、固定大小的最小二进制堆 ADT。当我测试我的程序时,我编写的所有函数似乎都工作正常,除了找到只应该返回存储在根节点的整数值的最小元素。此实现中的根节点位于索引 1 处。 我不断收到的错误是读取访问冲突。 下面是二叉堆类的定义和函数的实现:
class BinaryHeap {
public:
BinaryHeap(int); // constructor that takes the capacity of the structure
~BinaryHeap(); // destructor
void insert(int); // inserts a new element to the heap
void deleteMin(); // removes the minimum element from the heap
int getMin(); // returns the minimum element int the heap, returns -1 if the heap is empty
private:
int *heap; // array to store the elements of the heap
int size; // keeps the number of elements in the heap
int capacity; // keeps the total capacity of the heap
void percolateDown(int);
void percolateUp(int);
void swap(int, int);
};
BinaryHeap::BinaryHeap(int capacity) {
this->capacity = capacity;
heap = new int[capacity+1];
size = 0;
}
BinaryHeap::~BinaryHeap() {
delete [] heap;
}
void BinaryHeap::insert(int element) {
if (size < capacity) {
size++;
heap[size] = element;
percolateUp(size);
}
else return;
}
void BinaryHeap::deleteMin() {
if (size < 1)
return;
else {
heap[1] = heap[size];
size--;
percolateDown(1);
}
}
int BinaryHeap::getMin() {
if (size < 1)
return -1;
else return heap[1];
}
void BinaryHeap::percolateDown(int hole) {
int leftChildIndex, rightChildIndex, minIndex;
leftChildIndex = hole * 2;
rightChildIndex = hole * 2 + 1;
if (rightChildIndex >= size) {
if (leftChildIndex >= size) return;
else minIndex = leftChildIndex;
}
else {
if (heap[leftChildIndex] <= heap[rightChildIndex])
minIndex = leftChildIndex;
else
minIndex = rightChildIndex;
}
if (heap[hole] > heap[minIndex]) {
swap(hole, minIndex);
percolateDown(minIndex);
}
}
void BinaryHeap::percolateUp(int index) {
int parentIndex(1);
if (index != 1) {
parentIndex = index / 2;
}
if (heap[parentIndex] > heap[index]) {
swap(parentIndex, index);
percolateUp(parentIndex);
}
}
void BinaryHeap::swap(int i, int j) {
int t = heap[i];
heap[i] = heap[j];
heap[j] = t;
}
【问题讨论】:
-
我正在尝试实现一个基于数组的、固定大小的最小二进制堆 ADT -- 你不使用现成的heap functions 有什么原因吗?
-
为什么不在索引零处?
-
这是因为使用 leftchild=index*2、rightchild=index*2+1 和 parent=index/2 可以更轻松地访问子/父索引。 - - 所以你的教授正试图把一个方形钉子装进一个圆孔里。 C++ 从 0 开始数组,而不是 1。通过伪造一个基于 1 的数组,您可能会面临右边缘下降的风险,从而导致内存访问错误,或者错误地访问元素 0,从而导致错误的计算。相信我,我之前已经看过数百次了,编码人员正在尝试这样做,然后最终遇到这些问题。
-
相关:stackoverflow.com/a/49806133/56778。我认为你的导师应该读这个。还有stackoverflow.com/a/22900767/56778
标签: c++ data-structures