二叉树基础练习

前序遍历(先根遍历):根,左子树,右子树

中序遍历:左子树,根,右子树
后序遍历:左子树,右子树,根

先序遍历: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 = j; r < len && s[i+2][r] == ‘-‘; r++) ;
27             dfs(l+1, r, i+3);
28         }
29         putchar(‘)‘);
30     }
31 }
32 int main() {
33     int t;
34     scanf("%d%*c", &t);
35     while(t--) {
36         CLR(s, 0);
37         n = 0;
38         while(cin.getline(s[n], N, ‘\n‘)) {
39             if(strcmp(s[n], "#") == 0)
40                 break;
41             n++;
42         }
43         putchar(‘(‘);
44         if(n) dfs(0, strlen(s[0]), 0);
45         putchar(‘)‘);
46         puts("");
47     }
48     return 0;
49 }

0ms

UVA 536 Tree Recovery

题意:给出树的前序遍历和中序遍历,求此树的后序遍历。

 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 = 26+5;
15 char pre_order[N], in_order[N];
16 void dfs(int l1, int r1, int l2, int r2) {
17     if(l1 > r1) return;
18     int p = l2;
19     int rt = pre_order[l1];
20     while(in_order[p] != pre_order[l1]) p++;
21     int cnt = p - l2;
22     dfs(l1+1, l1+cnt, l2, p-1);
23     dfs(l1+cnt+1, r1, p+1, r2);
24     printf("%c", in_order[p]);
25 }
26 int main() {
27     while(~scanf("%s %s", pre_order, in_order)) {
28         int len = strlen(pre_order)-1;
29         dfs(0, len, 0, len);
30         puts("");
31     }
32     return 0;
33 }

0ms

时间: 2024-08-02 15:12:21

二叉树基础练习的相关文章

二叉树基础及应用

二叉树基础: 刚看到堆排序,顺便记录一下关于树的一些基本概念: 前言 前面介绍的栈.队列都是线性结构(linear structure).而树是非线性结构(non-linear structure).因此,树中的元素之间一般不存在类似于线性结构的一对一的关系,更多地表现为多对多的关系.直观地看,它是数据元素(在树中称为节点)按分支关系组织起来的结构.显然,树形结构是比线性结构更复杂的一种数据结构类型. 一.树 树的定义:树是含有n个节点的有穷集合,其中有一个节点比较特殊称为根节点.在图示树时,用

二叉树基础

一.二叉树深度优先遍历 只介绍先序遍历: (1) 第一种方法是使用stack的结构 (2) 主要要理解后面的分治法 Version 0: Non-Recursion (Recommend) /** * Definition for binary tree * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class

二叉树基础算法总结

记录一些二叉树的基础算法 二叉树节点结构: typedef struct TreeNode{ int val; struct TreeNode *left; struct TreeNode *right; }TreeNode,*Node; 1.遍历 前.中.后序递归遍历: void pre_order_traversal(TreeNode *root){ if(root! = NULL){ visit(root); pre_order_traversal(root->left); pre_ord

二叉树基础(创建方法,遍历方法(前序/中序/后序/层序、递归/非递归)

二叉树的创建及遍历是很多二叉树问题的基础,递归遍历逻辑清晰,代码简约漂亮,然则效率低下(所有递归方案的通病,非不得已不用递归): 非递归遍历高效,却不是能信手写出来的,特别是后续非递归遍历,相信很多资深码工也有这样的经历: 5年前学习了二叉树的非递归遍历,一个月前复习了并达到能熟练写出的程度,在不参考任何资料的情况下,今天却怎样也写不出来. 如果你也有过这种经历,恭喜你,这说明你是一个正常人…… 另一方面市面上有些国人写的教材,各种语法.逻辑错误层出不起,不知祸害了多少未来的码工,深感痛心. 印

【二叉树】 二叉树基础

在计算机科学中,二叉树是每个节点最多有两个子树的树结构.通常子树被称作"左子树"(left subtree)和"右子树"(right subtree).二叉树常被用于实现二叉查找树和二叉堆. 二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒.二叉树的第i层至多有个结点:深度为k的二叉树至多有个结点:对任何一棵二叉树T,如果其终端结点数为,度为2的结点数为,则. 树和二叉树的三个主要差别: 树的结点个数至少为1,而二叉树的

树、二叉树基础

刚看到堆排序,顺便记录一下关于树的一些基本概念: 前言 前面介绍的栈.队列都是线性结构(linear structure).而树是非线性结构(non-linear structure).因此,树中的元素之间一般不存在类似于线性结构的一对一的关系,更多地表现为多对多的关系.直观地看,它是数据元素(在树中称为节点)按分支关系组织起来的结构.显然,树形结构是比线性结构更复杂的一种数据结构类型. 一.树 树的定义:树是含有n个节点的有穷集合,其中有一个节点比较特殊称为根节点.在图示树时,用一条边连接两个

二叉树基础算法--遍历

二叉树的前序遍历(144. Binary Tree Preorder Traversal) 递归 1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10 class So

二叉树基础——前序遍历、中序遍历、后序遍历、按层遍历

转载请注明原文地址: 一:树的结点 一般默认树的结点由:结点值.左儿子.右儿子,构造函数组成. class TreeNode{ int value; TreeNode left; TreeNode right; public TreeNode(int i){ this.value=i; } } 二:二叉树的遍历实现--递归和非递归 1:递归实现==按照遍历方式(前.中.后)对左.根.右的访问顺序去 打印结点值.递归左儿子.递归右儿子 public void preorder(TreeNode r

树与二叉树基础算法的比较

一:树的创建 在数据结构中,树是以二叉树的形式储存的. 树转换为二叉树形式分为三步: ⑴加线——树中所有相邻兄弟之间加一条连线. ⑵去线——对树中的每个结点,只保留它与第一个孩子结点之间的连线,删去它与其它孩子结点之间的连线. ⑶层次调整——以根结点为轴心,将树顺时针转动一定的角度,使之层次分明. 转换后结果如图: 所以树的创建算法有两个思路: 1.将树转化为二叉树后,以二叉树中结点的关系输入而创建树. 2.直接以树中结点的关系输入,用代码转换为相应的二叉树. 第一种方法实际就是二叉树创建,只不