【牛客网】二叉树遍历(八)

题目:二叉树遍历

题目详情:

编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储);

例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树;

建立起此二叉树以后,再对二叉树进行中序遍历,输出遍历结果

输入描述:

输入包括1行字符串,长度不超过100

输出描述:

可能有多组测试数据,对于每组数据, 输出将输入字符串建立二叉树后中序遍历的序列,每个字符后面都有一个空格。 每个输出结果占一行

示例1:

输入:abc##de#g##f###

输出:c b e g d f a

以上呢就是题目的介绍了,言之呢就是让我们用一组前序遍历字符串组成一颗二叉树,然后再用中序遍历打印出来

那具体要怎么实现呢?我们且来分析一下!

【牛客网】二叉树遍历(八)_第1张图片

我们首先得了解一下前序遍历字符串的构成,以及他们之间的关系

我们知道用前序遍历来遍历树的访问顺序是:根结点-->左子树-->右子树

咱们看下前序遍历的代码

//前序遍历
void PrevOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("N ");
		return;
	}
 
	printf("%d ", root->data);
	PrevOrder(root->left);
	PrevOrder(root->right);
}

就用上面那个示例为例,我们首先得用这组字符串逆推组成二叉树,这是必要的!那要怎么推呢?就根据它的访问顺序即可,下面我们就来推演一下;

前序遍历字符串是:abc##de#g##f###

首先访问的是根结点所以 a 为根结点

前序遍历字符串是:abc##de#g##f### 

然后访问 a 的左子树 b

【牛客网】二叉树遍历(八)_第2张图片

前序遍历字符串是:abc##de#g##f### 

然后访问 b 的左子树 c

【牛客网】二叉树遍历(八)_第3张图片

前序遍历字符串是:abc##de#g##f###

然后访问 c 的左子树 #

【牛客网】二叉树遍历(八)_第4张图片

前序遍历字符串是:abc##de#g##f### 

因为 # 代表 NULL 所以返回到结点 c

然后访问 c 的右子树 #

【牛客网】二叉树遍历(八)_第5张图片

前序遍历字符串是:abc##de#g##f### 

因为 # 代表 NULL 所以返回到结点 c

然后对结点 c 访问结束返回到结点 b

然后访问 b 的右子树 d

【牛客网】二叉树遍历(八)_第6张图片

前序遍历字符串是:abc##de#g##f### 

然后访问 d 的左子树 e

【牛客网】二叉树遍历(八)_第7张图片

前序遍历字符串是:abc##de#g##f###  

然后访问 e 的左子树 #

【牛客网】二叉树遍历(八)_第8张图片

前序遍历字符串是:abc##de#g##f###  

因为 # 代表 NULL 所以返回到结点 e 

然后访问 e 的右子树 g 

【牛客网】二叉树遍历(八)_第9张图片

前序遍历字符串是:abc##de#g##f###  

然后访问 g 的左子树 #

【牛客网】二叉树遍历(八)_第10张图片

前序遍历字符串是:abc##de#g##f###  

因为 # 代表 NULL 所以返回到结点 g 

然后访问 g 的右子树 #

【牛客网】二叉树遍历(八)_第11张图片

前序遍历字符串是:abc##de#g##f###  

因为 # 代表 NULL 所以返回到结点 g 

然后对结点 g 访问结束返回到结点 e 

然后访问 e 的右子树 f 

【牛客网】二叉树遍历(八)_第12张图片

前序遍历字符串是:abc##de#g##f###  

然后访问 f 的左子树 #

【牛客网】二叉树遍历(八)_第13张图片

前序遍历字符串是:abc##de#g##f###  

因为 # 代表 NULL 所以返回到结点 f 

然后访问 f 的右子树 #

【牛客网】二叉树遍历(八)_第14张图片

前序遍历字符串是:abc##de#g##f###  

因为 # 代表 NULL 所以返回到结点 f 

然后对结点 f 访问结束返回到结点 d

然后对结点 d 访问结束返回到结点 b 

然后对结点 b 访问结束返回到结点 a 

然后访问 a 的右子树 #

【牛客网】二叉树遍历(八)_第15张图片

前序遍历字符串是:abc##de#g##f###  

因为 # 代表 NULL 所以返回到结点 a 

然后遍历也就结束了,就这么简单,思路捋清楚了,图画好了自然水到渠成;

树图示:

【牛客网】二叉树遍历(八)_第16张图片

以上就是用这组字符串逆推组成二叉树的演绎了; 

【牛客网】二叉树遍历(八)_第17张图片

然后我们就要用代码来表示这一切了!

我们先完成主函数里的框架然后再逐步实现,首先我们创建一个数组,内容用 gets( ) 函数来输入,然后就是用字符串来构造二叉树,然后再中序遍历打印树 ok 了;

int main() {
    char arr[100]={0};
    //输出字符串
    gets(arr);
    int i=0;
    //构造树
    BTNode* root=Great(arr,&i);
    //中序遍历打印
    PrevOrder(root);
    return 0;
}

然后我们来实现构造树函数 Great(arr,&i)

用前序遍历的方式(根结点-->左子树-->右子树)思路就是上述的图解,如果值为 # 就是 NULL ,直接返回 NULL ,不过 i 要继续往后走,然后构造树结点然后先让左子树也如此递归,然后就是右子树也递归构造结点,再返回根结点即可

BTNode* Great(char* arr,int* i)
{
    if(arr[(*i)]=='#')
    {
        (*i)++;
        return NULL;
    }
    BTNode* root=BuyNode(arr[(*i)++]);
    root->left=Great(arr,i);
    root->right=Great(arr,i);
    return root;
}

首先简单搭建一下树的基本信息;

typedef char BTDataType;
//二叉链
typedef struct BinaryTreeNode
{
	BTDataType data; // 当前结点值域	
	struct BinaryTreeNode* left; // 指向当前节点左孩子
	struct BinaryTreeNode* right; // 指向当前节点右孩子
}BTNode;

实现 BuyNode(arr[(*i)++]),动态创立新结点;

//动态创立新结点
BTNode* BuyNode(BTDataType x)
{
	BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));
	assert(newnode);
	newnode->data = x;
	newnode->left = NULL;
	newnode->right = NULL;
	return newnode;
}

然后再中序遍历(PrevOrder(root))打印树值即可;

void PrevOrder(BTNode* root)
{
    if(root==NULL)
    {
        return;
    }
    PrevOrder(root->left);
    printf("%c ",root->data);
    PrevOrder(root->right);
}

然后就。。。

【牛客网】二叉树遍历(八)_第18张图片

【牛客网】二叉树遍历(八)_第19张图片

源代码:

#include
#include
#include

typedef char BTDataType;
//二叉链
typedef struct BinaryTreeNode
{
	BTDataType data; // 当前结点值域	
	struct BinaryTreeNode* left; // 指向当前节点左孩子
	struct BinaryTreeNode* right; // 指向当前节点右孩子
}BTNode;

//动态创立新结点
BTNode* BuyNode(BTDataType x)
{
	BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));
	assert(newnode);
	newnode->data = x;
	newnode->left = NULL;
	newnode->right = NULL;
	return newnode;
}

BTNode* Great(char* arr,int* i)
{
    if(arr[(*i)]=='#')
    {
        (*i)++;
        return NULL;
    }
    BTNode* root=BuyNode(arr[(*i)++]);
    root->left=Great(arr,i);
    root->right=Great(arr,i);
    return root;
}

void PrevOrder(BTNode* root)
{
    if(root==NULL)
    {
        return;
    }
    PrevOrder(root->left);
    printf("%c ",root->data);
    PrevOrder(root->right);
}

int main() {
    char arr[100]={0};
    gets(arr);
    int i=0;
    BTNode* root=Great(arr,&i);
    PrevOrder(root);
    return 0;
}

【牛客网】二叉树遍历(八)_第20张图片

加油加油,冲冲冲!

后面博主会陆续更新;

如有不足之处欢迎来补充交流!

完结。


你可能感兴趣的:(算法,数据结构,开发语言,c语言,排序算法)