我一直试图实施Heap
数据类型,而且我已经碰壁了。
由于之前的许多答案都要求使用moar代码,因此它是:
#include <iostream>
#include <vector>
#include <iomanip>
using namespace std;
template <typename T> void display_array(vector<T> arr, bool endline = true)
{
cout << arr.size() << endl;
for (int i = 0; i < arr.size() - 1; i++) cout << arr[i] << ", ";
cout << arr[arr.size() - 1];
if(endline) cout << endl;
}
template <class T> class Heap
{
//typedef T Node;
// setw(...);
//private:
public:
vector<T>* elems;
Heap() : elems(nullptr)
{
this->elems = new vector<T>;
}
Heap(vector<T> e)
{
this->elems = new vector<T>(e);
}
Heap(vector<T>* e)
{
this->elems = e;
}
Heap(Heap<T>& h)
{
this->elems = new vector<T>(h.elems);
}
~Heap()
{
delete elems;
}
T elemAt (int index)
{
return (*(this->getElems())) [index];
}
vector<T>* getElems()
{
return this->elems;
}
int parent (int index)
{
return index / 2;
}
long getSize()
{
return this->getElems()->size();
}
int left (int index)
{
return 2 * index;
}
T leftElem (int index)
{
return this->elems [2 * index];
}
int right (int index)
{
return 1 + 2 * index;
}
T rightElem (int index)
{
return this->elems [1 + 2 * index];
}
bool withinHeap (int index)
{
return index <= (this->getSize());
}
void maxHeapify(int index)
{
int largest = index;
int l = left(index);
int r = right(index);
if (withinHeap(l) && elemAt(l) > elemAt(index))
{
if (withinHeap(r) && elemAt(r) > elemAt(l))
{
largest = r;
}
largest = l;
}
if (largest != index)
{
int temp = elemAt(index);
elemAt(index) = elemAt(largest);
elemAt(largest) = temp;
delete temp;
}
/* or return withinHeap(l) && elemAt(l) > elemAt(index) ? withinHeap(r) && elemAt(r) > elemAt(l) ? r : l : index; :) */
}
void display(int current, int indent)
{
if(withinHeap(left(current))) display(left(current), indent + 4);
if (indent > 0) cout << setw(indent) << " ";
cout << elemAt(current) << endl;
if(withinHeap(right(current))) display(right(current), indent + 4);
}
};
int main()
{
vector<int> vec {2, 5, 4, 12, 3, 9};
Heap<int>* h = new Heap<int>(vec);
display_array(*h->getElems());
h->display(0, 0);
return 0;
}
最后一个语句(h->display(0,0)
)会导致段错误。我已将其缩小到getSize()
函数。
在gdb中,print this.elems
和print *this.elems
是可以的(它们会返回对象跟踪或者它们被调用的任何内容),但是当我键入print *this.elems->size()
gdb回复
Cannot access memory at address 0xbf7fffef
我对C ++和gdb以及所有内容都很陌生。这里有什么问题?
答案 0 :(得分:2)
根据C ++技术(全部有效)对代码的所有评论,问题似乎是你的display
函数导致堆栈溢出。
如果您使用left()
实际执行的操作替换left()
的来电,您可以清楚地看到它:
void display(int current, int indent)
{
if (withinHeap(2 * current))
display(2 * current, indent + 4);
//...
}
如果我们调用display(0, 0);
,那么函数将无法返回,因为您在循环中使用相同的参数值调用display
。
withinHeap
除了检查参数是否在边界内之外没有做任何事情,并且不以任何方式更改Heap
对象。由于0
在范围内,因此对withinHeap
的调用始终返回true
。因此,从这个功能的开始你就遇到了麻烦。
我不会讨论如何解决这个问题,因为这是一个算法问题,而不是C ++问题。但是我指出的是你的代码导致错误的地方。