C++ Max Heap 在移除 max 后排序不正确
C++ Max Heap not sorting correctly after remove max
我试图通过交换向量的第一个和最后一个元素然后使用 pop_back 来删除最大值。当我删除 max 时,我输出 max 但重新排序过程无法正常工作,我无法弄清楚原因。
我多次尝试改变测试方式,但结果没有改变。谁能看出我哪里出错了?
#include <vector>
#include <string>
class Heap
{
public:
void insert(int data)
{
int parent = 0;
heap.push_back(data);
current = heap.size() - 1;
parent = (current - 1) / 2;
if (heap.size() > 1)
{
while (heap.at(parent) < heap.at(current))
{
if (heap.at(current) > heap.at(parent))
{
std::swap(heap.at(parent), heap.at(current));
current = parent;
parent = (parent - 1) / 2;
}
}
}
// for(int i = 0; i < heap.size(); i++)
// {
// std::cout << heap.at(i) << std::endl;
// }
// std::cout << std::endl;
}
void remove_max()
{
if (!heap.empty())
{
if (heap.size() == 1)
{
heap.pop_back();
return;
}
std::swap(heap.at(0), heap.at(heap.size() - 1));
heap.pop_back();
int parent = heap.at(0);
int lchild = (parent * 2) + 1;
int rchild = (parent * 2) + 2;
// while(lchild < heap.size() && rchild < heap.size())
// {
// if(heap.at(lchild) < heap.at(rchild))
// {
// std::swap(heap.at(parent), heap.at(rchild));
// parent = rchild;
// }
// else
// {
// std::swap(heap.at(parent), heap.at(lchild));
// parent = rchild;
// }
// lchild = (lchild * 2) + 1;
// rchild = (rchild * 2) + 2;
// }
if (lchild < rchild)
{
while (parent > lchild)
{
std::swap(heap.at(parent), heap.at(lchild));
lchild = (lchild * 2) + 1;
parent = (rchild - 1) / 2;
}
}
else
{
while (parent > rchild)
{
std::swap(heap.at(parent), heap.at(rchild));
rchild = (rchild * 2) + 2;
parent = (rchild - 1) / 2;
}
}
}
// for(int i = 0; i < heap.size(); i++)
// {
// std::cout << heap.at(i) << std::endl;
// }
// std::cout << std::endl;
return;
}
int max()
{
return heap.at(0);
}
bool empty()
{
return heap.empty();
}
private:
std::vector<int> heap;
int current = 0;
};
int main()
{
// TODO: implement!
Heap myHeap;
std::string command;
int data;
do
{
std::cin >> command;
if (command == "add")
{
std::cin >> data;
myHeap.insert(data);
}
else if (command == "run")
{
std::cout << myHeap.max() << std::endl;
myHeap.remove_max();
}
else if (command == "exit")
{
while (!myHeap.empty())
{
std::cout << myHeap.max() << std::endl;
myHeap.remove_max();
}
}
} while (command != "exit");
return 0;
}
你的数学完全错了。您将存储值与索引计算混淆了。在某些地方,您通过乘以索引来计算值,而在其他地方,您通过乘以存储的值来计算索引。那永远行不通。
void remove_max()
{
if (heap.empty())
return;
std::swap(heap.at(0), heap.at(heap.size() - 1));
heap.pop_back();
size_t parent = 0;
do
{
// get first child slot
size_t child = 2*parent + 1;
if (child < heap.size())
{
// calculate right-child index.
size_t rchild = 2*(parent+1);
if (rchild < heap.size() && heap[rchild] > heap[child])
child = rchild;
// got the child slot. now compare.
if (heap[child] > heap[parent])
{
std::swap(heap[child], heap[parent]);
parent = child;
}
else
{
// parent larger than children. stop here.
break;
}
}
else
{
// reached a node with no children
break;
}
} while (true);
}
我试图通过交换向量的第一个和最后一个元素然后使用 pop_back 来删除最大值。当我删除 max 时,我输出 max 但重新排序过程无法正常工作,我无法弄清楚原因。
我多次尝试改变测试方式,但结果没有改变。谁能看出我哪里出错了?
#include <vector>
#include <string>
class Heap
{
public:
void insert(int data)
{
int parent = 0;
heap.push_back(data);
current = heap.size() - 1;
parent = (current - 1) / 2;
if (heap.size() > 1)
{
while (heap.at(parent) < heap.at(current))
{
if (heap.at(current) > heap.at(parent))
{
std::swap(heap.at(parent), heap.at(current));
current = parent;
parent = (parent - 1) / 2;
}
}
}
// for(int i = 0; i < heap.size(); i++)
// {
// std::cout << heap.at(i) << std::endl;
// }
// std::cout << std::endl;
}
void remove_max()
{
if (!heap.empty())
{
if (heap.size() == 1)
{
heap.pop_back();
return;
}
std::swap(heap.at(0), heap.at(heap.size() - 1));
heap.pop_back();
int parent = heap.at(0);
int lchild = (parent * 2) + 1;
int rchild = (parent * 2) + 2;
// while(lchild < heap.size() && rchild < heap.size())
// {
// if(heap.at(lchild) < heap.at(rchild))
// {
// std::swap(heap.at(parent), heap.at(rchild));
// parent = rchild;
// }
// else
// {
// std::swap(heap.at(parent), heap.at(lchild));
// parent = rchild;
// }
// lchild = (lchild * 2) + 1;
// rchild = (rchild * 2) + 2;
// }
if (lchild < rchild)
{
while (parent > lchild)
{
std::swap(heap.at(parent), heap.at(lchild));
lchild = (lchild * 2) + 1;
parent = (rchild - 1) / 2;
}
}
else
{
while (parent > rchild)
{
std::swap(heap.at(parent), heap.at(rchild));
rchild = (rchild * 2) + 2;
parent = (rchild - 1) / 2;
}
}
}
// for(int i = 0; i < heap.size(); i++)
// {
// std::cout << heap.at(i) << std::endl;
// }
// std::cout << std::endl;
return;
}
int max()
{
return heap.at(0);
}
bool empty()
{
return heap.empty();
}
private:
std::vector<int> heap;
int current = 0;
};
int main()
{
// TODO: implement!
Heap myHeap;
std::string command;
int data;
do
{
std::cin >> command;
if (command == "add")
{
std::cin >> data;
myHeap.insert(data);
}
else if (command == "run")
{
std::cout << myHeap.max() << std::endl;
myHeap.remove_max();
}
else if (command == "exit")
{
while (!myHeap.empty())
{
std::cout << myHeap.max() << std::endl;
myHeap.remove_max();
}
}
} while (command != "exit");
return 0;
}
你的数学完全错了。您将存储值与索引计算混淆了。在某些地方,您通过乘以索引来计算值,而在其他地方,您通过乘以存储的值来计算索引。那永远行不通。
void remove_max()
{
if (heap.empty())
return;
std::swap(heap.at(0), heap.at(heap.size() - 1));
heap.pop_back();
size_t parent = 0;
do
{
// get first child slot
size_t child = 2*parent + 1;
if (child < heap.size())
{
// calculate right-child index.
size_t rchild = 2*(parent+1);
if (rchild < heap.size() && heap[rchild] > heap[child])
child = rchild;
// got the child slot. now compare.
if (heap[child] > heap[parent])
{
std::swap(heap[child], heap[parent]);
parent = child;
}
else
{
// parent larger than children. stop here.
break;
}
}
else
{
// reached a node with no children
break;
}
} while (true);
}