L2-012 关于堆的判断 (25 分)
将一系列给定数字顺序插入一个初始为空的小顶堆H[]
。随后判断一系列相关命题是否为真。命题分下列几种:
x is the root
:x
是根结点;x and y are siblings
:x
和y
是兄弟结点;x is the parent of y
:x
是y
的父结点;x is a child of y
:x
是y
的一个子结点。
输入格式:
每组测试第1行包含2个正整数N
(≤ 1000)和M
(≤ 20),分别是插入元素的个数、以及需要判断的命题数。下一行给出区间[−10000,10000]内的N
个要被插入一个初始为空的小顶堆的整数。之后M
行,每行给出一个命题。题目保证命题中的结点键值都是存在的。
输出格式:
对输入的每个命题,如果其为真,则在一行中输出T
,否则输出F
。
输入样例:
5 4
46 23 26 24 10
24 is the root
26 and 23 are siblings
46 is the parent of 23
23 is a child of 10
输出样例:
F
T
F
T
堆其实算是一种完全二叉树(完全二叉树用数组存储较为方便),根据结点从0进行编号,父结点n的两个子节点的编号一定是2*n+1和2*n+2;
#include <iostream>
#include<string>
using namespace std;
void creat(int H[], int len) {
for (int i = 1; i < len; i++) {
int j = i;
int father = (j - 1) / 2;
while (father != j && H[father] > H[j]) {
swap(H[father], H[j]);
j = father;
father = (j - 1) / 2;
}
}
}
int getIndex(int array[], int data, int len) {
for (int i = 0; i < len; i++)
if (array[i] == data)
return i;
return -1;
}
bool judge(int array[], int len, int a, int b, string link) {
if (link == "root")
return getIndex(array, a, len) == 0;
else if (link == "siblings")
return (getIndex(array, a, len) - 1) / 2 == (getIndex(array, b, len) - 1) / 2;
else if (link == "parent")
return (getIndex(array, b, len) - 1) / 2 == getIndex(array, a, len);
else
return (getIndex(array, a, len) - 1) / 2 == getIndex(array, b, len);
}
int main() {
int n, m, H[1000], a = -1, b = -1;
string link, str;
cin >> n >> m;
for (int i = 0; i < n; i++)
cin >> H[i];
creat(H, n);
for (int i = 0; i < m; i++) {
cin >> a >> str;
if (str == "and")
cin >> b >> str >> link;
else {
cin >> str >> link;
if (link != "root")
cin >> str >> b;
}
cout << (judge(H, n, a, b, link) ? "T" : "F") << endl;;
}
return 0;
}
建堆方式优化:
#include <iostream>
#include<string>
using namespace std;
void insert(int H[], int last) {
int father = (last - 1) / 2;
while (father != last && H[father] > H[last]) {
swap(H[father], H[last]);
last = father;
father = (last - 1) / 2;
}
}
int getIndex(int array[], int data, int len) {
for (int i = 0; i < len; i++)
if (array[i] == data)
return i;
return -1;
}
bool judge(int array[], int len, int a, int b, string link) {
if (link == "root")
return getIndex(array, a, len) == 0;
else if (link == "siblings")
return (getIndex(array, a, len) - 1) / 2 == (getIndex(array, b, len) - 1) / 2;
else if (link == "parent")
return (getIndex(array, b, len) - 1) / 2 == getIndex(array, a, len);
else
return (getIndex(array, a, len) - 1) / 2 == getIndex(array, b, len);
}
int main() {
int n, m, H[1000], a = -1, b = -1;
string link, str;
cin >> n >> m;
for (int i = 0; i < n; i++) {
cin >> H[i];
insert(H,i);
}
for (int i = 0; i < m; i++) {
cin >> a >> str;
if (str == "and")
cin >> b >> str >> link;
else {
cin >> str >> link;
if (link != "root")
cin >> str >> b;
}
cout << (judge(H, n, a, b, link) ? "T" : "F") << endl;;
}
return 0;
}