二叉树基础练习

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 }
50ms

UVA 548 Tree

题意:给一棵带权树的中序和后序遍历,找一个叶子使得它到根的路径的权值尽可能小,若有多解取叶子权值小的。

题解:后序遍历的最后一个字符就是根,然后在中序遍历中找到根,从而找出左右子树的节点,递归构造左右子树。再DFS遍历找最优解。

yy:string和stringstream用法总结

 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 }
80ms

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 }
0ms

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 }
0ms

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 }
10ms

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 }
20ms

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

以上是关于二叉树基础练习的主要内容,如果未能解决你的问题,请参考以下文章

数据结构之二叉树基础OJ练习单值二叉树

数据结构——二叉树的基础练习题(单值二叉树,翻转二叉树,相同的树,对称二叉树,另一颗子树,二叉树的前序遍历)

数据结构之二叉树的基础OJ练习二叉树的遍历

二叉树基础练习

数据结构二叉树基础oj练习2(源码+算法思路)

基础练习区间DPcodevs1090 加分二叉树题解