上篇文章中,对二叉树基本操作的前提是我们手动构建了一颗二叉树,那么二叉树正确的构建方式是怎样的呢,这篇文章通过牛客网 练习题:KY11 二叉树遍历 来对正确构建二叉树进行讲解。
目录
做题链接如下:
题目描述
手动输入先序遍历字符串,则是先序构建成二叉树,之后中序遍历输出。
分析
以: abc##de#g##f### 为例,前序构建二叉树
中序遍历输出:c b e g d f a
前序遍历规则:先访问根 再访问左子树 最后访问右子树
那么创建时也遵循这个规则
先创建根,再创建左子树,最后创建右子树
图解如下
代码实现
定义二叉树结点
#include <stdio.h>
typedef struct BinaryTreeNode
{
char data;
struct BinaryTreeNode*left;
struct BinaryTreeNode*right;
}BTNode;
创建数组,输入相应字符串
定义i变量,作为数组下标,方便读取字符
int main()
{
char a[100];
scanf("%s",a);
int i=0;
//创建二叉树,返回地址,方便下一步中序遍历
BTNode* root=CreatBTree(&a,&i);
//中序遍历
InOrder(root);
return 0;
}
前序创建二叉树
判断是否为 '#' , # 为空,返回NULL;
动态开辟二叉树结点,将字符放入结点数据域中
更新下标
此时根节点创建好,下一步创建左子树;
最后一步创建右子树;
注:函数参数要传下标地址
传值的话i为栈帧中局部变量,返回上一层树时,局部变量销毁,i还相当于上一层树的初始下标。
BTNode* CreatBTree(char* a,int* i)
{
if(a[*i]=='#')
{
(*i)++;
return NULL;
}
BTNode* node=(BTNode*)malloc(sizeof(BTNode));
if(node==NULL)
{
exit(-1);
}
node->data=a[(*i)++];
node->left=CreatBTree(a,i);
node->right=CreatBTree(a,i);
return node;
}
中序遍历
void InOrder(BTNode* tree)
{
if(tree==NULL)
{
return;
}
InOrder(tree->left);
printf("%c ",tree->data);
InOrder(tree->right);
}
到这整个题目各部分代码就完成了。
从前序构建可推出中序构建和后序构建,构建与遍历在结构上相似,可以对照理解。
中序构建二叉树
BTNode* CreatBTree(char* a,int* i)
{
if(a[*i]=='#')
{
(*i)++;
return NULL;
}
BTNode* node=(BTNode*)malloc(sizeof(BTNode));
if(node==NULL)
{
exit(-1);
}
node->left=CreatBTree(a,i);
node->data=a[(*i)++];
node->right=CreatBTree(a,i);
return node;
}
后序构建二叉树
BTNode* CreatBTree(char* a,int* i)
{
if(a[*i]=='#')
{
(*i)++;
return NULL;
}
BTNode* node=(BTNode*)malloc(sizeof(BTNode));
if(node==NULL)
{
exit(-1);
}
node->left=CreatBTree(a,i);
node->right=CreatBTree(a,i);
node->data=a[(*i)++];
return node;
}