初学二叉树


前言

    在学习了树,二叉树的相关内容后去写了一下题目,结果发现布置的二叉树的入门题是和前序,中序,后序遍历相关的。(这下我就要搜索不管你链表结构了


P1305 新二叉树

题目描述

输入一串二叉树,输出其前序遍历。

输入格式

第一行为二叉树的节点数 n。(1≤n≤26)

后面 n 行,每一个字母为节点,后两个字母分别为其左右儿子。特别地,数据保证第一行读入的节点必为根节点。

空节点用 * 表示

输出格式

二叉树的前序遍历。

输入输出样例

输入 #1

6
abc
bdi
cj*
d**
i**
j**

输出 #1

abdicj 

 题目分析

     将每行视为一个高为2的完美二叉树,那么可以借助链表的思想建立一个存储节点信息的逻辑链表(说穿了就是数组,比较菜是这样的)然后就可以通过递归的方式先查找左子树再查找右子树;若此时查询到的为“*”则说明该节点为叶子节点,return 即可


代码示例

 

#include <stdio.h>

typedef struct fi{
    char a, b;
}f;

char rt, l, r;
f st[200];

void dfs(char rt) {
    if(rt == '*' || rt == 0) return ;//0防止hack数据不展示全部节点,进入未标记的空链死循环
    printf("%c", rt);
    dfs(st[(int)rt].a);
    dfs(st[(int)rt].b);
    return ;
}
 
int main() {
    int n;
    char temp;
    scanf("%d", &n);
    //getchar();
    scanf(" %c %c %c", &rt, &l, &r);
    st[(int)rt].a = l, st[(int)rt].b = r;
    for(int i = 2; i <= n; i++) {
        //getchar();
        scanf(" %c", &temp);
        scanf(" %c %c", &st[(int)temp].a, &st[(int)temp].b);
        //printf("%c%c%c\n", temp,st[(int)temp].a, st[(int)temp].b);
    }
    //printf("\n\n");
    /*for(int i = 'a'; i <= 'z'; i++) {
        if(st[(int)i].a != 0){
        printf("%c%c%c\n", i,st[(int)i].a, st[(int)i].b);
        }
    }*/
    dfs(rt);
    return 0;
}

在代码实现的时候发现getcahr()消去换行符不知道为啥会爆内存,所以只能读入的时候加个空格了


 P1827 [USACO3.4] 美国血统 American Heritage

题目描述

农夫约翰非常认真地对待他的奶牛们的血统。然而他不是一个真正优秀的记帐员。他把他的奶牛 们的家谱作成二叉树,并且把二叉树以更线性的“树的中序遍历”和“树的前序遍历”的符号加以记录而 不是用图形的方法。

你的任务是在被给予奶牛家谱的“树中序遍历”和“树前序遍历”的符号后,创建奶牛家谱的“树的 后序遍历”的符号。每一头奶牛的姓名被译为一个唯一的字母。(你可能已经知道你可以在知道树的两 种遍历以后可以经常地重建这棵树。)显然,这里的树不会有多于 26 个的顶点。

这是在样例输入和样例输出中的树的图形表达方式:

         C
         /  \
        /  \
       B    G
      / \  /
       A   D  H
        / \
       E   F

附注:

  • 树的中序遍历是按照左子树,根,右子树的顺序访问节点;
  • 树的前序遍历是按照根,左子树,右子树的顺序访问节点;
  • 树的后序遍历是按照左子树,右子树,根的顺序访问节点。

输入格式

第一行一个字符串,表示该树的中序遍历。

第二行一个字符串,表示该树的前序遍历。

输出格式

单独的一行表示该树的后序遍历。

输入输出样例

输入 

ABEDFCHG
CBADEFGH 

输出

AEFDBHGC

题目分析 

    前,中,后序排列的基本知识,但本题也能递归搜索解决,没必要重建树(前 + 中;后 + 中;均能重建树);


代码示例

#include <stdio.h>
#include <string.h>

const int N = 30;
char a[N];//中序
char b[N];//前序

void dfs(int x, int y, int p, int q) { //指针
    if(x > y || p > q) return ; //边界
    for(int i = x; i <= y; i++){
        if(a[i] == b[p]) { //前序首节点为树根
            dfs(x, i - 1, p + 1, p + i - x); //拆出该节点对应左子树
            dfs(i + 1, y, p + i - x + 1, q); //拆出该节点对应右子树
            printf("%c", a[i]); //输出节点
        }
    }
    
}


int main() {
    scanf("%s", a);
    scanf("%s", b);
    int len = strlen(a) - 1;
    dfs(0, len, 0, len);
    return 0;
}

  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值