二叉树遍历 (牛客网)
题目要求:
编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉树以后,再对二叉树进行中序遍历,输出遍历结果。
输入描述:输入包括1行字符串,长度不超过100。
输出描述:可能有多组测试数据,对于每组数据, 输出将输入字符串建立二叉树后中序遍历的序列,每个字符后面都有一个空格。 每个输出结果占一行。
示例1
输入:
abc##de#g##f###
输出:
c b e g d f a
思路:
(要点须知:1.先序遍历:先看root(根节点),再左孩子节点,最后右孩子节点
2.中序遍历:先看左孩子节点,再看root,最后看右孩子节点 )
题目要求需要先将读入的字符通过先序遍历的方式创建二叉树,再对二叉树进行中序遍历进行输出。我们可以创建一个二叉树建立函数(先序遍历)和一个中序遍历显示函数。我们需要得到每个二叉树节点,都可以往下找其左孩子节点和右孩子节点,可以创建一个结构体,分别存放左孩子节点的地址、右孩子节点的地址、原节点的数值。
(1)二叉树创建函数
题目规定输入数值大小不超过100,可以通过sacnf函数先将数值存入一个101大小的数组中(保守起见,比需求大1格,‘\0’需要占一格)。可以从前到后对数组进行个遍历,对每一个值进行判断。数值为不为‘#’,就创建节点,将数值存入val变量中。再判断数组下一个数值是否为‘#’,如果是就让其父亲节点指向NULL,不创建节点;否则就创建节点,并将数值赋值给该节点的val变量,最后将该节点地址赋给其父亲节点。
为了方便理解,我们看下面的图来捋清楚思路。下面的1、2、3、4、5、6、7分别是先序遍历创建二叉树的步骤,这只是我们眼中的步骤,和题目需要的有所差异。实际上根据题目要求,在第3步后面会判断c节点的左孩子和有孩子有没有数值,没有数值就返回NULL,然后再继续去下一个有数值的节点,反复上述操作。可以看出c节点下面没有数值,所以按题目要求这两个值都是’'#",并给c节点的左孩子和右孩子指针赋值NULL,不创建其左右孩子节点。然后就跳到d节点,循环往复,直道g节点左右都没数值,整棵树都没有可以创建的节点,那么这棵二叉树就创建完成了。
本文用的是递归的方式创建二叉树,先判断一下结束条件,创建二叉树有两种情况,一种是空树(NULL),不需要创建节点;一种有数值,需要创建节点。第一种情况可以作为特殊情况,放在前面判断,是就直接结束返回NULL,不继续后面的操作。第二种作为正常情况处理,创建节点,给节点的val变量赋值,再继续判断左右节点,最后再返回自己节点的地址。这样可以保证每个存在的节点,其左右节点都会被遍历,且都有节点地址。
(2)中序遍历函数
下图为中序遍历,和上面一样,1-7为遍历顺序。
中序遍历函数依旧用递归方式进行遍历。先确定结束条件,当寻找的地址为NULL时结束。所以可以将其作为特殊情况先判断,是就结束,否则就继续正常情况。中序遍历,先左、再root、最后右。那就对应顺序,先判断左节点,再显示root节点,最后判断右节点。如果存在数值就会往左孩子去找,左孩子没有节点,下一个就会显示原节点的数值;如果左孩子有节点,那就会继续往下找。(右孩子也一样,就是顺序不同而已)
#include <stdio.h>
#include <stdlib.h>
struct BinaryTree
{
struct BinaryTree* left;//指向该节点的左孩子节点的地址
struct BinaryTree* right;//指向该节点的右孩子节点的地址
char val;//该节点的数值
};
struct BinaryTree* CreatTree(char* arr, int* pi)//二叉树创建函数
{
if(arr[(*pi)] == '#')
{
(*pi)++;
return NULL;
}
struct BinaryTree* newnode = (struct BinaryTree*)malloc(sizeof(struct BinaryTree));//创建节点
newnode->val = arr[(*pi)++];
newnode->left = CreatTree(arr, pi);
newnode->right = CreatTree(arr, pi);
return newnode;//返回节点地址
}
void InOrder(struct BinaryTree* root)//中序遍历函数
{
if(root == NULL)
{
return;//无返回值并结束
}
InOrder(root->left);
printf("%c ", root->val);
InOrder(root->right);
}
int main() {
char arr[101] = " ";
scanf("%s", arr);
int i = 0;
struct BinaryTree*root = CreatTree(arr, &i);
InOrder(root);
return 0;
}
题目链接:https://www.nowcoder.com/practice/4b91205483694f449f94c179883c1fef?tpId=60&&tqId=29483&rp=1&ru=/activity/oj&qru=/ta/tsing-kaoyan/question-ranking
如有不当之处,感谢各位大佬指正。