我实现了一个堆类,它接受一个布尔值作为构造函数参数,该值指定对象应该是最小堆还是最大堆。 getTop()方法应返回并从最大堆中删除最大值。
如果我这样初始化堆:
Heap maxHeap(true); // This will be a max heap.
int values[]{1, 5, 3, 2, 10, 7};
for (const int &value : values) {
maxHeap.insert(value);
}
根据我写cout的方式,我得到两个不同的输出:
cout << maxHeap.getTop() << endl
<< maxHeap.getTop() << endl
<< maxHeap.getTop() << endl;
// Output: 5
// 7
// 10
与下面的块相比,它也恰好具有所需的输出:
cout << maxHeap.getTop() << endl;
cout << maxHeap.getTop() << endl;
cout << maxHeap.getTop() << endl;
// Output: 10
// 7
// 5
用整数文字替换 maxheap.getTop()将导致正确的行为,两种方式之间没有区别。阅读类似的Stack Overflow帖子,我了解到C ++标准没有为具有相同优先级的运算符指定顺序。第一个代码块与整数文字一起正常工作只是巧合吗?什么可能导致这种行为?任何有关这方面的见解将不胜感激。
编辑:下面是我的Heap类的代码。
class Heap {
public:
vector<int> v;
bool isMax;
Heap(bool isMax) : isMax(isMax) {
// Don't use first element.
v.push_back(-1);
}
Heap &insert(int value) {
v.push_back(value);
swim(v.size() - 1);
return *this;
}
int getTop() {
int topValue = v[1];
v[1] = v.back();
v.pop_back();
sink(1);
return topValue;
}
int size() {
return v.size() - 1;
}
private:
void swim(int index) {
while (!isOrdered(index)){
swap(index / 2, index);
index /= 2;
}
}
void sink(int index) {
int childIndex = findReplacementIndex(index);
while (childIndex > 0) {
if (!isOrdered(childIndex)) {
swap(childIndex / 2, childIndex);
index = childIndex;
}
else {
break;
}
childIndex = findReplacementIndex(index);
}
}
int findReplacementIndex(int parentIndex) {
if (2 * parentIndex >= v.size()) {
return -1;
}
else if (2 * parentIndex + 1 >= v.size()) {
return 2 * parentIndex;
}
else if (isMax) {
return v[2 * parentIndex] > v[2 * parentIndex + 1] ?
2 * parentIndex : 2 * parentIndex + 1;
}
else {
return v[2 * parentIndex] < v[2 * parentIndex + 1] ?
2 * parentIndex : 2 * parentIndex + 1;
}
}
void swap(int index1, int index2) {
int tmp = v[index1];
v[index1] = v[index2];
v[index2] = tmp;
}
bool isOrdered(int childIndex) {
if (childIndex < 2 || childIndex >= v.size()) {
return true;
}
int parent = v[childIndex / 2];
int child = v[childIndex];
return isMax ? parent > child : parent < child;
}
};