【数据结构17】二叉树OJ题之二叉树遍历及构建


题目

题目来源牛客网:https://www.nowcoder.com/practice/4b91205483694f449f94c179883c1fef?tpId=60&&tqId=29483&rp=1&ru=/activity/oj&qru=/ta/tsing-kaoyan/question-ranking
描述
编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉树以后,再对二叉树进行中序遍历,输出遍历结果。
输入描述:
输入包括1行字符串,长度不超过100。
输出描述:
可能有多组测试数据,对于每组数据, 输出将输入字符串建立二叉树后中序遍历的序列,每个字符后面都有一个空格。 每个输出结果占一行
在这里插入图片描述

核心思路

1.首先把树创建出来
只要这个树的前序包含树的所有元素(空节点也在内)便能复原整颗树
前序:根、左子树、右子树
创建树的过程
在这里插入图片描述
先建立根,前序遍历的第一个数据就是树的根
在这里插入图片描述
再创建根的左孩子,只要没遇到空,就一直创建左孩子(根的左孩子,根的左孩子的左孩子,这样一直创建下去)
根的左子树全部创建完后,就开始创建根的右孩子,然后开始创建右子树
在这里插入图片描述
遇到空了说明该节点的左孩子为空,接来下就该节点创建右孩子
在这里插入图片描述
创建完后,如果右孩子还有孩子,就先创建左孩子
如果没有则返回创建上一层的右孩子,如果上一层的右孩子还有孩子,就先创建左孩子
在这里插入图片描述
如果左孩子还有孩子,就先创建左孩子的左孩子,左孩子的左子树全部创立完后,再创建右孩子
如果没有就直接创建右孩子
在这里插入图片描述
创建右孩子后,如果右孩子还有孩子就先创建以右孩子为根节点的左右子树,如果右孩子没有孩子了再创建上一层的右孩子。
在这里插入图片描述
在这里插入图片描述
由上面构建树的过程我们可以知道,最核心的思路便是先构建根,再构建左子树,最后构建右子树,按这样的思路一层一层递归下去

2.树创建完成后再打印树的中序
中序:左子树、根、右子树
在这里插入图片描述
中序输出:先输出左子树,如果左子树全部输出完毕,再输出根,如果根全部输出完毕,再输出右子树。
根的左子树又可以划分为根,左子树,右子树。
根的右子树又可以划分为根、左子树、右子树。
所以可以一层一层递归下去不断输出,直到达到终止条件
中序输出:#c#b##egd#f#a#

代码

#include <stdio.h>
#include <stdlib.h>
typedef char BTDatatype;
struct TreeNode
{
    BTDatatype val;
    struct TreeNode* left;
    struct TreeNode* right;
};
//建树的过程
struct TreeNode* CreateTree(BTDatatype* str,int* pi)
{
	//为空则返回
    if(str[*pi] == '#')
    {
        (*pi)++;
        return NULL;
    }

    struct TreeNode* root = (struct TreeNode*)malloc(sizeof(struct TreeNode));
    //先建根
    root->val = str[(*pi)++];
    //再建左子树
    root->left = CreateTree(str,pi);
    //最后建右子树
    root->right = CreateTree(str,pi);

    return root;
}
//输出树的中序
void InOrder(struct TreeNode* root)
{
    if(root == NULL)
    {
        return ;
    }
    InOrder(root->left);
    printf("%c ",root->val);
    InOrder(root->right);
}

int main() 
{
    char str[100] = {0};
    scanf("%s",str);
    int i = 0;
    struct TreeNode* root = CreateTree(str,&i);
    InOrder(root);








    return 0;
}

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值