在判断是否符合堆的特性时,我一开始使用的判断语句是:
if ((heap[root] > heap[2 * root] || heap[root] > heap[2 * root + 1])
&& (heap[2 * root]!= -999999 && heap[2 * root + 1]!= -999999))
flag_min = 0;//不是小根堆;
虽然我将每个空节点都设置为了-999999.但是这样有一个致命的错误,就是root*2可能超过设置的数组长度。导致错误。
后来改为了:
if (2 * root <= N && heap[root] > heap[2 * root]) flag_min = 0;
if (2 * root + 1 <= N && heap[root] > heap[2 * root + 1]) flag_min = 0;
这样可以直接防止数据越界。
#include<bits/stdc++.h>
using namespace std;
vector<int> heap(1009),ans;
int flag_min, flag_max;
int M, N;
void preTraversal(int root) {
if (root > N) return;
preTraversal(root * 2);
preTraversal(root * 2 + 1);
ans.push_back(heap[root]);
}
void judge_maxheap(int root) {
if (root > N) return;
//出错的地方
//----------------------------------------------------------------------//
if (2 * root <= N && heap[root] < heap[2 * root]) flag_max = 0;
if (2 * root + 1 <= N && heap[root] < heap[2 * root + 1]) flag_max = 0;
//----------------------------------------------------------------------//
judge_maxheap(root * 2);
judge_maxheap(root * 2 + 1);
}
void judge_minheap(int root) {
if (root > N) return;
//----------------------------------------------------------------------//
if (2 * root <= N && heap[root] > heap[2 * root]) flag_min = 0;
if (2 * root + 1 <= N && heap[root] > heap[2 * root + 1]) flag_min = 0;
//----------------------------------------------------------------------//
judge_minheap(root * 2);
judge_minheap(root * 2 + 1);
}
int judge() {
if (heap[1] > heap[2]) {//当大根堆判断
flag_min = 0;
judge_maxheap(1);
if(flag_max == 1)
return 1;
}
else if (heap[1] < heap[2]) {//当小根堆判断
flag_max = 0;
judge_minheap(1);
if(flag_min == 1)
return 1;
}
else {
judge_minheap(1); judge_maxheap(1);
if (flag_max + flag_min == 1) return 1;
}
return 0;
}
int main() {
#ifdef ONLINE_JUDGE
#else
freopen("Text.txt", "r", stdin);
#endif // ONLINE_JUDGE
cin >> M >> N;
for (int j = 0; j < M; j++) {
flag_min = 1; flag_max = 1;
fill(heap.begin(), heap.end(), -999999);
for (int i = 1; i <= N; i++) {
cin >> heap[i];
}
if (judge() == 1) {
if (flag_max == 1) cout << "Max Heap" << endl;
else cout << "Min Heap" << endl;
}
else {
cout << "Not Heap" << endl;
}
preTraversal(1);
cout << ans[0];
for (int i = 1; i < N; i++)
cout << " " << ans[i];
cout << endl;
ans.clear();
}
}