题目链接:二叉树遍历__牛客网 (nowcoder.com)
我们先画图顺序一下我们的结构
题目要求:我们看到题目要求是输入一个先序遍历的一个字符串#代表空格,空格代表空树!我们需要先通过先序遍历的一个字符串的逻辑结构建立我们二叉树的物理结构保存在我们的内存中,通过我们的调用内存去实现我们的二叉树的中序遍历。
主要思路:
1.创建一个数组去保存我们的前序遍历字符串。
2.创建一个结构体需要有我们当前root的数据val。
3.我们创造一个函数去使用我们的数组去构建我们的二叉树这个函数需要返回我们的root节点的地址所以函数的返回类型是结构体指针类型,函数需要传主函数开辟的root,和数组,以及一个可以根据数据从数组从前到后变化的i的数值。
4.在函数主体内容中我们如果递归到#字符就返回NULL,其他情况。
5.我们需要动态开辟我们结构体节点的存放位置存放我们当前的root,然后去递归遍历我们的左子树和我们的右子树。我们进入递归的时候我们就可以把root->left 和我们的root->right 当成我们递归左右子树的数的根节点这就是我们递归的主要思路!
代码实现:
6.我们的二叉树的物理结构已经在内存中构建好了,我们在写完一个功能的时候我们可以去编译执行一下程序去检查一下有没有问题!
7.通过我们主函数返回出来的root的地址去打印我们中序遍历的结果就非常简单了中序遍历是左子树根右子树这样的一个结构。我们进入函数的时候应该先进入左再去根再去右!这样的过程去递归实现;
代码实现:
全部代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
//定义我们的结构体
typedef struct TreeNode {
char val;
struct TreeNode* left;
struct TreeNode* right;
}TNode;
TNode* Creatree(char* str, int* n)
{
//传i的地址才可以保证我们构建过程中的稳定
if (str[*n] == '#')
{
//表示就没有左或者右的节点内容我们就递归回去
//注意空也是我们数组的内容
(*n)++;
return NULL;
}
//递归有节点的情况:构建我们的节点
TNode* root =(TNode*) malloc(sizeof(TNode));
//判断动态开辟是否成功!
if (root == NULL)
{
printf("malloc fail \n");
exit(-1);
}
//这里需要i一直++不能因为进入函数而变化!
root->val = str[*n];
(*n)++;
//这里之后我们就可以
//把我们左右节点的地址当成他们各自左右节点的地址,
//在一次进入我们的函数!
root->left= Creatree(str, n);
root->right= Creatree(str,n);
//这里是不是需要返回我们的root
return root;
}
//中序遍历函数
void Inorde(TNode* root)
{
if (root == NULL)
{
return;
}
//不是空的话我们需要打印我们的节点
//中序
Inorde(root->left);
printf("%c ", root->val);
Inorde(root->right);
}
int main()
{
//输入我们的字符串!
char str[100];
scanf("%s", str);
//根据逻辑结构构建物理结构,
//通过root可以很好的实现我们的前中后序遍历打印
int i = 0;
TNode* root = Creatree(str, &i);
//中序打印
Inorde(root);
return 0;
}
把代码放到牛客平台上面显示通过所有测试用例。大家也去试一试吧!