下面给出的是我用自己的堆实现编写的驱动程序。
#include<iostream>
#include"Heap.h"
int main(){
Heap h(30);
h.insert(1);
h.insert(3);
h.insert(5);
h.insert(6);
h.insert(5);
h.insert(8);
h.display();
std::cout<<h.extractMin(); // Statement 1
h.display();
}
这给出了所需的结果:
========= Heap Contents =========
1 3 5 6 5 8
1
========= Heap Contents =========
3 6 5 8 5
但是,如果我将statement 1
更改为:
std::cout<<"Min: "<<h.extractMin();
代码开始给出分段错误。同样,如果我将statement 1
更改为
int z = h.extractMin();
代码仍然给出了分段错误。这诱惑我看看我在extractMin()
做错了什么。以下是我对extractMin()
的定义:
int Heap::extractMin()
{
int min = this -> arr[0];
this -> arr[0] = this -> arr[heapSize];
heapSize -= 1;
heapify(0);
return min;
}
为了完整起见,下面是我对heapify()
的定义:
void Heap::heapify(int index){
if(index > this -> heapSize)
return;
int smallest = index;
int l = leftChild(index);
int r = rightChild(index);
if(l <= heapSize && arr[l] < arr[index])
smallest = l;
if(r <= heapSize && arr[r] < smallest)
smallest = r;
if(smallest != index){
arr[smallest] = arr[smallest] ^ arr[index];
arr[index] = arr[smallest] ^ arr[index];
arr[smallest] = arr[smallest] ^ arr[index];
heapify(smallest);
}
}
知道发生了什么事吗?我无法理解分段错误背后的原因。我有什么明显的遗失吗?
谢谢!
h.getHeapSize()
和h.getArrSize()
也会发生这种情况,这让我觉得问题在于其他问题,而不在函数中。
整个代码如下:
#include<iostream>
#include<cmath>
class Heap{
private:
int* arr;
int size;
int heapSize;
public:
Heap(int = 8);
Heap(int*, int size);
int* initArr(int size);
void setSize(int);
int getSize();
int getHeapSize();
void setHeapSize(int);
int leftChild(int);
int rightChild(int);
int parent(int);
void heapify(int);
void buildHeap();
void insert(int);
int extractMin();
void display() const;
};
Heap::Heap(int size){
initArr(size);
this -> size = size;
this -> heapSize = -1;
}
Heap::Heap(int* arr, int size){
this -> arr = arr;
this -> size = size;
this -> heapSize = size - 1;
buildHeap();
}
int* Heap::initArr(int size){
int* arr = new int[size];
return arr;
}
void Heap::setSize(int size){
if(size > this -> heapSize)
this -> size = size;
}
int Heap::getSize(){
return this -> size;
}
void Heap::setHeapSize(int heapSize){
this -> heapSize = heapSize;
}
int Heap::getHeapSize(){
return this -> heapSize;
}
int Heap::leftChild(int index){
return 2*index + 1;
}
int Heap::rightChild(int index){
return 2*index + 2;
}
int Heap::parent(int index){
return ceil(index >> 1) - 1;
}
void Heap::heapify(int index){
if(index > this -> heapSize)
return;
int smallest = index;
int l = leftChild(index);
int r = rightChild(index);
if(l <= heapSize && arr[l] < arr[index])
smallest = l;
if(r <= heapSize && arr[r] < smallest)
smallest = r;
if(smallest != index){
arr[smallest] = arr[smallest] ^ arr[index];
arr[index] = arr[smallest] ^ arr[index];
arr[smallest] = arr[smallest] ^ arr[index];
heapify(smallest);
}
}
void Heap::buildHeap(){
for(int i = heapSize/2 - 1; i >= 0; i-- )
heapify(i);
}
void Heap::insert(int val){
heapSize += 1;
int loc = heapSize;
arr[heapSize] = val;
int p;
while((p = arr[parent(heapSize)]) > val){
arr[loc] = arr[p] ^ arr[loc];
arr[p] = arr[p] ^ arr[loc];
arr[loc] = arr[p] ^ arr[loc];
}
}
int Heap::extractMin(){
//int temp = arr[0];
//arr[0] = arr[heapSize];
//arr[heapSize] = temp;
int min = arr[0];
arr[0] = arr[heapSize];
heapSize -= 1;
heapify(0);
//return arr[heapSize + 1];
return min;
}
void Heap::display() const{
std::cout<<"\n========= Heap Contents =========\n";
for(int i = 0; i <= heapSize; i++)
std::cout<<arr[i]<<'\t';
std::cout<<'\n';
}
答案 0 :(得分:0)
从你在这里发布的内容来看,堆大小的不当处理是罪魁祸首。涉及heapSize
的所有测试似乎都没有考虑到基于零的访问。你应该真的改变它,因为它会导致许多非逻辑后果:heapSize是否被初始化为-1
?
至于调试:
heapSize
,还包括0)修改强>
该错误发生在parent()
。尝试调试技巧。
答案 1 :(得分:0)
有很多问题。
首先,采用int
参数的构造函数不会初始化arr
成员,它会分配内存并将其分配给本地指针变量,它返回但只是忽略返回值。
你必须将它存储在成员变量中(将局部变量命名为与成员相同通常是一个非常糟糕的主意。)
修复后:在第一次插入期间,h.insert(1);
,parent(heapSize)
为-1
由于您使用它在数组中进行索引,因此程序具有未定义的行为并且所有注意都已关闭;该程序不是一个有效的C ++程序。
也可能存在其他问题,但这些问题最为明显。