7-3 Structure of Max-Heap (25 分)
#include<iostream>
using namespace std;
int n, m, tree[100005];
void siftup(int i)
{
while(i != 1)// 只要比父节点大,就一直与父节点交换,往上跳,直到根或不大于父亲为止
{
if(tree[i] > tree[i/2])
{
swap(tree[i], tree[i/2]);
i = i / 2; //向上跳到父亲节点
}
else
break;
}
}
int find(int x)
{
for(int i = 1; i <= n; i++)
if(tree[i] == x) //如果找到x,说明在tree中i代表的是x
return i;
return -1;
}
int main()
{
cin >> n >> m; //读入n个数字,m个查询
for(int i = 1; i <= n; i++) //建立大根堆
{
cin >> tree[i];
siftup(i);
}
/* 这样子遍历就是按照层序的方式将大根堆遍历出来
for(int i=1; i<=n; i++)
cout << tree[i] << " ";*/
int a, b;
string s1, s2;
for(int i = 0; i < m; i++) //下面进行m个操作
{
cin >> a >> s1;
if(s1 == "and") //这个代表a,b是左右兄弟节点
{
cin >> b >> s2 >> s2; //如果是左右兄弟节点肯定有相同的父亲节点
if(find(a) / 2 == find(b) / 2 && find(a) != -1 && find(b) != -1)
cout << 1;
else
cout << 0;
}
else
{
cin >> s1 >> s1;
if(s1 == "root")
{
if(find(a) == 1) //1代表根节点
cout << 1;
else
cout << 0;
}
else if(s1 == "parent") //a是b的父亲
{
cin >> s2 >> b;
if(find(b) / 2 == find(a) && find(a) != -1 && find(b) != -1)
cout << 1;
else
cout << 0;
}
else if(s1 == "left") //a是b的左儿子
{
cin >> s2 >> s2 >> b;
if(find(a) == find(b)*2 && find(a) != -1 && find(b) != -1)
cout << 1;
else
cout << 0;
}
else if(s1 == "right") //a是b的右儿子
{
cin >> s2 >> s2 >> b;
if(find(a) == find(b)*2+1 && find(a) != -1 && find(b) != -1)
cout << 1;
else
cout << 0;
}
}
}
return 0;
}
7-4 Cartesian Tree (30 分)
题目描述
A Cartesian tree is a binary tree constructed from a sequence of distinct numbers. The tree is heap-ordered, and an inorder traversal returns the original sequence. For example, given the sequence { 8, 15, 3, 4, 1, 5, 12, 10, 18, 6 }, the min-heap Cartesian tree is shown by the figure.
Your job is to output the level-order traversal sequence of the min-heap Cartesian tree.
Input Specification:
Each input file contains one test case. Each case starts from giving a positive integer N(≤30)N(≤30), and then NN distinct numbers in the next line, separated by a space. All the numbers are in the range of int.
Output Specification:
For each test case, print in a line the level-order traversal sequence of the min-heap Cartesian tree. All the numbers in a line must be separated by exactly one space, and there must be no extra space at the beginning or the end of the line.
Sample Input:
10
8 15 3 4 1 5 12 10 18 6
Sample Output:
1 3 5 8 4 6 15 10 12 18
//已知一个大根堆的中序遍历,构建一个大根堆,完了,输出层序遍历法
#include<iostream>
#include<unordered_map>
using namespace std;
const int maxn=33;
int in[maxn],q[maxn];
int n;
unordered_map<int,int> L,R;
int get_min(int l,int r)
{
int t=-1;
for(int i=l; i<=r; i++)
if(t==-1 || in[t]>in[i])
t=i;
return t;
}
int build(int l,int r)
{
int root=get_min(l,r);
if(root>l)
L[root]=build(l,root-1);
if(root<r)
R[root]=build(root+1,r);
return root;
}
void bfs(int root)
{
int hh=0,tt=0;
q[0]=root;
while(hh<=tt)
{
int t=q[hh++];
if(L.count(t))
q[++tt]=L[t];
if(R.count(t))
q[++tt]=R[t];
}
cout << in[q[0]];
for(int i=1; i<n; i++)
cout << " " << in[q[i]];
}
int main()
{
cin >> n;
for(int i=0; i<n; i++)
cin >> in[i];
int root=build(0,n-1);
bfs(root);
}