我需要这个minheap代码的帮助:
#include < vector>
using namespace std;
class heap {
vector <int> v;
public:
int hSize()
{
return v.size();
}
int rsize()
{
return hSize() - 1;
}
int parent(int i)
{
return (i - 1) / 2;
}
int left(int i)
{
return i * 2 + 1;
}
int right(int i)
{
return i * 2 + 2;
}
void swap(int i, int j)
{
int temp = v[j];
v[j] = v[i];
v[i] = temp;
}
void push(int e)
{
v.push_back(e);
int id = rsize();
if (hSize() > 1)
while (v[parent(id)] > v[id]) {
swap(parent(id), id);
id = parent(id);
}
}
int pop ()
{
int f = 0;
int p = v[0];
v[0] = v[rsize()];
if (hSize() > 1) {
while (v[left(f)] < v[f] || v[right(f)] < v[f]) {
if (v[left(f)] < v[f] && v[right(f)] < v[f]) {
if (v[left(f)] < v[right(f)]) {
swap(left(f), f);
f = left(f);
}
else {
swap(right(f), f);
f = right(f);
}
}
else {
if (v[left(f)] < v[f]){
swap(left(f), f);
f = left(f);
}
else {
swap(right(f), f);
f = right(f);
}
}
}
}
else { }
v.resize(rsize());
return p;
}
void show()
{
if (hSize() > 0) {
cout << "Heap content: ";
for (int i = 0; i < hSize(); i++) cout << v[i] << " ";
}
else cout << "\nHeap successfully emptied!";
cout << "\n";
}
bool Empty()
{
return v.empty();
}
~heap()
{
v.clear();
}
};
嗯,代码几乎可以正常运行,除非它弹出屏幕上的最后一个元素,它会打印一个随机数。你有什么看法?
谢谢!
答案 0 :(得分:2)
您有两个类似的问题,一个在push()
,另一个在pop()
。在推送中,您需要在查看id != 0
之前检查v[parent(id)]
。如果id == 0
你在根,你应该停止。同样,在pop()
中,您应该在访问right(f)
(或left(f)
)之前检查向量中是否v[right(f)]
(或v[left(f)]
)。如果不是,那么你已经到了堆的底部,你应该停止。
答案 1 :(得分:1)
<强>调试强>
<强>编码强>
你应该使用断言。例如,swap
函数的第一行可以是assert(i >= 0 && i < v.size());
,j
也是如此。我怀疑这两个断言会告诉你错误。当你完成后,如果你愿意,你可以注释掉断言(尽管有些人总是喜欢留下一些断言)。
<强>更新强> 你的代码没问题。只需要在swap内添加边界检查,如果不满意则返回。这是代码和测试用例(当我运行时通过):
#include <vector>
#include <iostream>
#include <cassert>
#include <cstdlib>
using namespace std;
class heap {
vector <int> v;
public:
int hSize()
{
return v.size();
}
int rsize()
{
return hSize() - 1;
}
int parent(int i)
{
return (i - 1) / 2;
}
int left(int i)
{
return i * 2 + 1;
}
int right(int i)
{
return i * 2 + 2;
}
void swap(int i, int j)
{
//assert(i >= 0 && i < v.size());
//assert(j >= 0 && j < v.size());
if(i >= v.size() || j >= v.size()) return;
int temp = v[j];
v[j] = v[i];
v[i] = temp;
}
void push(int e)
{
v.push_back(e);
int id = rsize();
if (hSize() > 1)
while (v[parent(id)] > v[id]) {
swap(parent(id), id);
id = parent(id);
}
}
int pop ()
{
int f = 0;
int p = v[0];
v[0] = v[rsize()];
if (hSize() > 1) {
while (v[left(f)] < v[f] || v[right(f)] < v[f]) {
if (v[left(f)] < v[f] && v[right(f)] < v[f]) {
if (v[left(f)] < v[right(f)]) {
swap(left(f), f);
f = left(f);
}
else {
swap(right(f), f);
f = right(f);
}
}
else {
if (v[left(f)] < v[f]){
swap(left(f), f);
f = left(f);
}
else { swap(right(f), f);
f = right(f);
}
}
}
}
else { }
v.resize(rsize());
return p;
}
void show()
{
if (hSize() > 0) {
cout << "Heap content: ";
for (int i = 0; i < hSize(); i++) cout << v[i] << " ";
}
else cout << "\nHeap successfully emptied!";
cout << "\n";
}
bool Empty()
{
return v.empty();
}
~heap()
{
v.clear();
}
};
int main()
{
heap h;
for(int i = 0; i < 10; i++) {
h.push(rand()%10);
h.push(4);
h.push(3);
h.push(2);
h.push(1);
h.push(0);
h.push(5);
h.push(-6);
h.push(7);
h.show();
h.pop();
h.pop();
h.pop();
h.pop();
h.pop();
h.pop();
h.pop();
h.pop();
h.pop();
h.show();
}
}
在断言之后,我在调试器中运行代码,发现崩溃发生在行swap(right(f), f);
中,而right(f)
超出范围。