二叉树基础练习
Posted GraceSkyer
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树基础练习相关的知识,希望对你有一定的参考价值。
前序遍历(先根遍历):根,左子树,右子树
中序遍历:左子树,根,右子树
后序遍历:左子树,右子树,根
先序遍历:ABDECF
中序遍历:DBEAFC
后序遍历:DEBFCA
层次遍历:ABCDEF
UVA 112 Tree Summing
题目:给你一个数和一棵树,问是否存在根到叶子的路径使得路径上的数字和与已知数相等。
注意数据中可能有负数
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 #include<string> 7 #include<cmath> 8 #include<vector> 9 #include<stack> 10 #include<map> 11 using namespace std; 12 #define CLR(a,b) memset((a),(b),sizeof((a))) 13 #define lson id*2 14 #define rson id*2+1 15 typedef long long ll; 16 typedef unsigned long long ull; 17 typedef pair<int, int>pii; 18 const int inf = 0x3f3f3f3f; 19 int n; 20 char input() { 21 char c; 22 scanf("%c", &c); 23 while(c == \' \' || c == \'\\n\') scanf("%c", &c); 24 return c; 25 } 26 int solve(int v, int *leaf) { 27 int l = 0, r = 0, f = 0; 28 int value; 29 scanf("%d", &value); 30 char c = input(); 31 32 if(c == \'(\') { 33 if(solve(v - value, &l)) f = 1; 34 c = input(); 35 if(solve(v - value, &r)) f = 1; 36 c = input(); 37 if(l && r && v == value) f = 1; 38 } 39 else *leaf = 1; 40 41 return f; 42 } 43 int main() { 44 int t; 45 while(~scanf("%d", &n)) { 46 input(); 47 if(solve(n, &t)) puts("yes"); 48 else puts("no"); 49 } 50 return 0; 51 }
UVA 548 Tree
题意:给一棵带权树的中序和后序遍历,找一个叶子使得它到根的路径的权值尽可能小,若有多解取叶子权值小的。
题解:后序遍历的最后一个字符就是根,然后在中序遍历中找到根,从而找出左右子树的节点,递归构造左右子树。再DFS遍历找最优解。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #include<string> 6 #include<sstream> 7 using namespace std; 8 #define CLR(a,b) memset((a),(b),sizeof((a))) 9 #define lson id*2 10 #define rson id*2+1 11 typedef long long ll; 12 typedef unsigned long long ull; 13 const int inf = 0x3f3f3f3f; 14 const int N = 1e5+5; 15 int lch[N], rch[N], in_order[N], post_order[N]; 16 int n; 17 int build(int l1, int r1, int l2, int r2) { 18 if(l1 > r1) return 0; //空树返回0 19 int rt = post_order[r2]; //根 20 int cnt, p = l1; 21 while(in_order[p] != rt) p++; 22 cnt = p - l1; //左子树节点个数 23 lch[rt] = build(l1, p-1, l2, l2+cnt-1);//递归构造左子树 24 rch[rt] = build(p+1, r1, l2+cnt, r2-1);//递归构造右子树 25 return rt;//返回根 26 } 27 int best, best_sum; 28 void dfs(int u, int sum) { 29 sum += u; 30 if(!lch[u] && !rch[u]) { //叶子 31 if(sum < best_sum || (sum == best_sum && u < best)) { 32 best_sum = sum; 33 best = u; 34 } 35 } 36 if(lch[u]) dfs(lch[u], sum); 37 if(rch[u]) dfs(rch[u], sum); 38 } 39 bool input(int *a) { 40 string line; 41 if(!getline(cin, line)) return false; 42 stringstream ss(line); 43 int x; 44 n = 0; 45 while(ss >> x) a[n++] = x; 46 return n > 0; 47 } 48 int main() { 49 while(input(in_order)) { 50 input(post_order); 51 build(0, n-1, 0, n-1); 52 best_sum = inf; 53 dfs(post_order[n-1], 0); 54 printf("%d\\n", best); 55 } 56 return 0; 57 }
UVA 297 Quadtrees (四分树)
求两棵四分树合并之后黑色像素的个数。(给出两棵四分树的先序遍历,p表示中间节点,f表示黑色,e表示白色)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #include<string> 6 #include<sstream> 7 using namespace std; 8 #define CLR(a,b) memset((a),(b),sizeof((a))) 9 #define lson id*2 10 #define rson id*2+1 11 typedef long long ll; 12 typedef unsigned long long ull; 13 const int inf = 0x3f3f3f3f; 14 const int N = 1024+5; 15 const int len = 32+5; 16 char s[N]; 17 int vis[len][len]; 18 int ans; 19 void dfs(int &cnt, int x, int y, int L) { 20 char c = s[cnt++]; 21 if(c == \'p\') { 22 dfs(cnt, x, y, L / 2); //1 23 dfs(cnt, x + L/2, y, L / 2); //2 24 dfs(cnt, x + L/2, y + L/2, L / 2); //3 25 dfs(cnt, x, y + L/2, L / 2); //4 26 } 27 else if (c == \'f\') { 28 for(int i = x; i < x+L; ++i) { 29 for(int j = y; j < y+L; ++j) { 30 if(!vis[i][j]) { 31 vis[i][j] = 1; 32 ans++; 33 } 34 } 35 } 36 } 37 } 38 int main() { 39 int t; 40 scanf("%d", &t); 41 while(t--) { 42 CLR(vis, 0); 43 ans = 0; 44 45 scanf("%s", s); 46 int cnt = 0; 47 dfs(cnt, 0, 0, 32); 48 49 scanf("%s", s); 50 cnt = 0; 51 dfs(cnt, 0, 0, 32); 52 printf("There are %d black pixels.\\n", ans); 53 } 54 return 0; 55 }
UVA 712 S-Trees
题意:给出一个不超过7层的满二叉树,然后给出满二叉树的叶子节点的值(0或1),给出路径(0往左走,1往右走)并输出每条路径到达叶子节点的值。
题解:0:L=L*2; 1:L=L*2+1; 叶子L=L-2^n+1
(注意输入格式%1d)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #include<string> 6 #include<sstream> 7 using namespace std; 8 #define CLR(a,b) memset((a),(b),sizeof((a))) 9 #define lson id*2 10 #define rson id*2+1 11 typedef long long ll; 12 typedef unsigned long long ull; 13 const int inf = 0x3f3f3f3f; 14 const int N = 8; 15 char s[30]; 16 int a[1<<N], ans[1<<N]; 17 int n, m; 18 int main() { 19 int k = 1; 20 while(~scanf("%d", &n), n) { 21 getchar();//吸收回车 22 cin.getline(s, 25, \'\\n\');//第二行无用 23 for(int i = 1; i <= (1<<n); ++i) 24 scanf("%1d", &a[i]); //注意输入格式 存叶子值 25 scanf("%d", &m); 26 int o; 27 for(int i = 0; i < m; ++i) { 28 int x = 1;//根 29 for(int j = 1; j <= n; ++j) { 30 scanf("%1d", &o); 31 x = 2*x + o; 32 } 33 x -= ((1<<n)-1);//叶子结点 34 ans[i] = a[x]; 35 } 36 printf("S-Tree #%d:\\n", k++); 37 for(int i = 0; i < m; ++i) 38 printf("%d", ans[i]); 39 printf("\\n\\n"); 40 } 41 return 0; 42 }
UVA 699 The Falling Leaves
题意: 给一棵树,每棵树有一个叶子,叶子的值是点权,求叶子垂直落下后, (同一个方向的形成一堆),求每堆叶子的总权值。
注意:一行数据不一定是一颗完整的树 。
题解:这里根从N/2开始,-1,+1进行建树,先序遍历
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #include<string> 6 #include<sstream> 7 using namespace std; 8 #define CLR(a,b) memset((a),(b),sizeof((a))) 9 #define lson id*2 10 #define rson id*2+1 11 typedef long long ll; 12 typedef unsigned long long ull; 13 const int inf = 0x3f3f3f3f; 14 const int N = 210; 15 int a[N], x; 16 void dfs(int pos, int x) { 17 a[pos] += x; 18 scanf("%d", &x); 19 if(x != -1) 20 dfs(pos-1, x);//左子树 21 scanf("%d", &x); 22 if(x != -1) 23 dfs(pos+1, x);//右子树 24 } 25 int main() { 26 int k = 1; 27 while(1) { 28 int f = 0; 29 CLR(a, 0); 30 scanf("%d", &x); 31 if(x == -1) break; 32 dfs(N/2, x); 33 printf("Case %d:\\n", k++); 34 for(int i = 0; i < N; ++i) { 35 if(a[i]) { 36 if(f) printf(" %d", a[i]); 37 else { f = 1; printf("%d", a[i]); } 38 } 39 } 40 printf("\\n\\n"); 41 } 42 return 0; 43 }
UVA 839 Not so Mobile
题意:每个秤都是一个树的结构,已知秤两边的重量和到支点的距离,问秤能否平衡
题解:dfs判断每个节点是否都平衡。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #include<string> 6 #include<sstream> 7 using namespace std; 8 #define CLR(a,b) memset((a),(b),sizeof((a))) 9 #define lson id*2 10 #define rson id*2+1 11 typedef long long ll; 12 typedef unsigned long long ull; 13 const int inf = 0x3f3f3f3f; 14 const int N = 8; 15 bool dfs(int &s) { 16 int wl, dl, wr, dr, a=1, b=1; 17 scanf("%d%d%d%d", &wl, &dl, &wr, &dr); 18 if(!wl) a = dfs(wl); 19 if(!wr) b = dfs(wr); 20 s = wl + wr; //为上层传值 21 if(a && b && wl*dl == wr*dr) return 1; 22 return 0; 23 } 24 int main() { 25 int t, x; 26 scanf("%d", &t); 27 while(t--) { 28 x = 0; 29 if(dfs(x)) puts("YES"); 30 else puts("NO"); 31 if(t) puts(""); 32 } 33 return 0; 34 }
UVA 10562 Undraw the Trees
题意:根据题目所给出的图写出多叉树。
题解:每三行看作一组数据,先序遍历。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #include<string> 6 #include<sstream> 7 using namespace std; 8 #define CLR(a,b) memset((a),(b),sizeof((a))) 9 #define lson id*2 10 #define rson id*2+1 11 typedef long long ll; 12 typedef unsigned long long ull; 13 const int inf = 0x3f3f3f3f; 14 const int N = 205; 15 char s[N][N]; 16 int n; 17 void dfs(int a, int b, int i) { 18 for(int j = a; j < b; ++j) { 19 if(s[i][j] == \' \' || s[i][j] == \'\\0\') continue; 20 putchar(s[i][j]); 21 putchar(\'(\'); 22 if(i+1 < n && s[i+1][j] == \'|\') { 23 int l, r; 24 for(l = j; l >= 0 && s[i+2][l] == \'-\'; l--) ; 25 int len = strlen(s[i+2]); 26 for(r以上是关于二叉树基础练习的主要内容,如果未能解决你的问题,请参考以下文章