<数据结构>由SearchTree的遍历序列确定树
XDOJ315. 拓展先序遍历-->二叉树
问题与解答
问题描述
编一个程序,读入用户输入的一串扩展先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的扩展先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉树以后,再对二叉树进行中序遍历,输出遍历结果。
输入格式
输入包括1行字符串,长度不超过100。
输出格式
输出将输入字符串建立二叉树后中序遍历的序列,每个字符后面都有一个空格。每个输出结果占一行。
样例输入
abc##de#g##f###
样例输出
c b e g d f a
样例说明
根据给定的扩展先序遍历序列,建立对应的二叉树,然后对所得的二叉树进行中序遍历输出结果即可。
/*先序遍历转中序遍历*/
/*数组树只能表示完全二叉树*/
#include<stdio.h>
#include<stdlib.h>
typedef struct TreeNode
{
char _val;
struct TreeNode* pleft;
struct TreeNode* pright;
}TreeNode;
TreeNode* CreateTree(char* arr,int *pi)
{
/*4. 递归终止条件*/
if (arr[*pi] == '#')
{
return NULL;
}
else
{
/*1. 递归操作:处理单个节点*/
TreeNode * root = (TreeNode *)malloc (sizeof(TreeNode));
root->_val = arr[*pi] ;
++(*pi);
/*2. 递归式:缩小问题规模*/
root->pleft = CreateTree(arr,pi);
++(*pi);
root->pright = CreateTree(arr,pi);
/*无需 ++(*pi); */
/*3. 返回值*/
return root;
}
}
void InorderTraversal(TreeNode * root)
{
if (root == NULL)
{
return ;
}
InorderTraversal(root->pleft);
printf("%c ",root->_val);
InorderTraversal(root->pright);
}
int main()
{
char arr[100];
scanf("%s",arr);
int i = 0;
TreeNode * root = CreateTree(arr,&i);
InorderTraversal(root);
return 0;
}
题后反思:数组树的不足
- 只有在表示完全二叉树的时候更方便:用数组表示非完全二叉树是所需要的附加操作不足可能比实现二叉链表树更加繁琐。
- 空间有限:数组不能开太大。
- 不方便用遍历操作,基本操作集合还没构建模板,要现场实现。
XDOJ318.先序+中序-->二叉树
问题与解答
问题描述
给定一棵二叉树的先序遍历和中序遍历序列,求其后序遍历序列。
输入格式
输入数据有两行,为两个字符串,其长度n均小于等于26。第一行为先序遍历序列,第二行为中序遍历序列。
二叉树中的结点名称以大写字母表示:A,B,C....最多26个结点。
输出格式
在一行上输出后序遍历序列。
样例输入
ABC
BAC
样例输出
BCA
步骤
1. 先序确定根结点
2. 在中序序列中找到根节点,从而确定左右子树
3. 递归解决
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MaxNum 30
struct TNode;
typedef struct TNode* Position;
typedef Position BT;
struct TNode
{
char Element;
BT LT;
BT RT;
};
BT BuildTree(char *pre, char *in, int n);
void PostOrderTraverse(BT T);
int main()
{
char pre[MaxNum], in[MaxNum];
int n;
BT T;
gets(pre);
gets(in);
n = strlen(pre);
T = BuildTree(pre,in,n);
PostOrderTraverse(T);
return 0;
}
/*输入:先序序列pre、中序序列in、待构建的树节点数n*/
BT BuildTree(char *pre, char *in, int n)
{
Position Parent;
char *p;
int k;
/*4. 终止条件:终止递归,弹栈*/
if(n==1)
{
Parent = (Position)malloc(sizeof(struct TNode));
Parent->Element = *pre;
Parent->LT = NULL;
Parent->RT = NULL;
return Parent;
}
/*1. 递归操作:处理单个节点*/
/*先序确定父节点,中序中找到该节点确定左右子树*/
for(p=in;p<in+n;p++)
if(*p==*pre) break;
k = p-in; //父节点对应下标
Parent = (Position)malloc(sizeof(struct TNode));
Parent->Element = *pre;
Parent->LT = NULL;
Parent->RT = NULL;
/*2. 递归式:对左右子树重复操作,缩小问题范围*/
if(k) //存在左子树
Parent->LT = BuildTree(pre+1, in, k); //左子树节点数为k
if(n-k-1) //存在右子树
Parent->RT = BuildTree(pre+k+1, p+1, n-k-1); //右子树节点数为(n-1)-k
/*3. 返回值*/
return Parent;
}
void PostOrderTraverse(BT T)
{
if(T)
{
PostOrderTraverse(T->LT);
PostOrderTraverse(T->RT);
printf("%c", T->Element);
}
}
题后反思:左右子树赋零
(忽略了子树赋零)
构建树结点:赋值完后需要把左右子树赋零
XDOJ320.层序+中序-->二叉树
问题与解答
问题描述
给定二叉树T(树深度H<=10,深度从1开始,结点个数N<1024,结点编号1~N)的层次遍历序列和中序遍历序列,输出T从左向右叶子结点以及二叉树先序和后序遍历序列。
输入格式
输入共三行:第一行是整数n,表示二叉树中的结点数目;第二行有n个整数,表示该二叉树的层次遍历序列;第三行也是n个整数,表示该二叉树的中序遍历序列。整数间以空格隔开。
输出格式
输出三行,分别是:从左向右的叶子结点,先序遍历序列,后序遍历序列。结点编号用空格隔开。
样例输入
7
3 5 4 2 6 7 1
2 5 3 6 4 7 1
样例输出
2 6 1
3 5 2 4 6 7 1
2 5 6 1 7 4 3
层序确定根节点,中序确定左右子树位置,遍历解决
/*层序+中序 确定树*/
/*输出:叶子结点*/
/*输出:先序、后序*/
#include<stdio.h>
#include<stdlib.h>
struct TNode;
typedef struct TNode* Position;
typedef Position BT;
struct TNode
{
int Element;
BT LT;
BT RT;
};
BT BuildTree(int *level, int *in, int levelL, int levelR, int inL, int inR);
void PreOrderTraverse(BT T);
void PostOrderTraverse(BT T);
void LeafNode(BT T); //打印叶子结点
int main()
{
int i,n;
BT T;
scanf("%d",&n);
int level[n], in[n];
for(i=0; i<n; i++)
scanf("%d", &level[i]);
for(i=0; i<n; i++)
scanf("%d", &in[i]);
T = BuildTree(level, in, 0, n-1, 0, n-1);
LeafNode(T);
printf("\n");
PreOrderTraverse(T);
printf("\n");
PostOrderTraverse(T);
printf("\n");
// InOrderTraverse(T);
// printf("\n");
return 0;
}
//当前二叉树的 层序区间[levelL,levelR], 中序区间[inL,inR]
BT BuildTree(int *level, int *in, int levelL, int levelR, int inL, int inR)
{
/*4. 终止条件: 子树无结点*/
if(inL > inR)
{
return NULL;
}
int i,j,flag=0;
Position Parent;
/*1. 递归操作:处理单个节点,即父节点Parent*/
Parent = (Position)malloc(sizeof(TNode));
Parent->LT = NULL;
Parent->RT = NULL; //不要忘记哦~~
//找到当前层序序列中 第一个 出现在当前中序序列的元素 赋值
for(i = levelL; i <= levelR; i++){
for(j = inL; j <= inR; j++){
if(level[i] == in[j]){
flag = 1;
break;
}
}
if(flag == 1) break;
}
Parent->Element = level[i];
/*2. 递归式:确定左右子树,缩小问题范围*/
Parent->LT = BuildTree(level, in, levelL+1, levelR, inL, j-1); //层序序列指针+1,左子树区间[inL, j-1]
Parent->RT = BuildTree(level, in, levelL+1, levelR, j+1, inR); //层序序列指针+1,右子树区间[j+1, inR]
/*3. 返回值*/
return Parent; //不要忘记哦~~
}
void LeafNode(BT T)
{
if(T){
if (T->LT == NULL && T->RT == NULL) {
printf("%d ", T->Element);
}
else {
LeafNode(T->LT);
LeafNode(T->RT);
}
}
}
void PreOrderTraverse(BT T)
{
if(T)
{
printf("%d ", T->Element);
PreOrderTraverse(T->LT);
PreOrderTraverse(T->RT);
}
}
void PostOrderTraverse(BT T)
{
if(T)
{
PostOrderTraverse(T->LT);
PostOrderTraverse(T->RT);
printf("%d ", T->Element);
}
}
void InOrderTraverse(BT T)
{
if(T)
{
InOrderTraverse(T->LT);
printf("%d ", T->Element);
InOrderTraverse(T->RT);
}
}
总结
- 都需要中序: X+中序
- X确定结点,中序确定左右子树位置
- 递归求解
<数据结构>由SearchTree的遍历序列确定树的更多相关文章
- 数据结构之 图论---基于邻接矩阵的广度优先搜索遍历(输出bfs遍历序列)
数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历 Time Limit: 1000MS Memory limit: 65536K 题目描述 给定一个无向连通图,顶点编号从0到n-1,用广度优先搜索( ...
- PAT-1086(Tree Traversals Again)Java语言实现+根据中序和前序遍历构建树并且给出后序遍历序列
Tree Traversals Again Tree Traversals Again 这里的第一个tip就是注意到非递归中序遍历的过程中,进栈的顺序恰好是前序遍历的顺序,而出栈的顺序恰好是中序遍历的 ...
- C++版 - 剑指offer 面试题24:二叉搜索树BST的后序遍历序列(的判断) 题解
剑指offer 面试题24:二叉搜索树的后序遍历序列(的判断) 题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则返回true.否则返回false.假设输入的数组的任意两个 ...
- LeetCode---105. 从前序与中序遍历序列构造二叉树 (Medium)
题目:105. 从前序与中序遍历序列构造二叉树 根据一棵树的前序遍历与中序遍历构造二叉树. 注意: 你可以假设树中没有重复的元素. 例如,给出 前序遍历 preorder = [3,9,20,15,7 ...
- 【PHP数据结构】完全二叉树、线索二叉树及树的顺序存储结构
在上篇文章中,我们学习了二叉树的基本链式结构以及建树和遍历相关的操作.今天我们学习的则是一些二叉树相关的概念以及二叉树的一种变形形式. 完全二叉树 什么叫完全二叉树呢?在说到完全二叉树之前,我们先说另 ...
- 剑指Offer面试题:22.二叉搜索树的后序遍历序列
一.题目:二叉搜索树的后序遍历序列 题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则返回true,否则返回false.假设输入的数组的任意两个数字都互不相同. 例如在下面 ...
- (剑指Offer)面试题24:二叉搜索树的后序遍历序列
题目: 输入一个整数数组,判断该数组是不是某个二叉搜索树的后序遍历的结果,如果是则返回true,否则返回false. 假设输入的数组的任意两个数字都互不相同. 思路: 根据二叉搜索树的后序遍历特点,很 ...
- 1048 图的宽度优先遍历序列 c语言
描述 图(graph)是数据结构 G=(V,E),其中V是G中结点的有限非空集合,结点的偶对称为边(edge):E是G中边的有限集合.设V={0,1,2,……,n-1},图中的结点又称为顶点(vert ...
- 基于visual Studio2013解决面试题之0208二叉搜索树后序遍历序列
题目
随机推荐
- json模块中函数的用法
json模块中主要使用四个函数:json.load(),json.dump(),json.loads(),json.dumps() json.loads()是将一个json编码的字符串转换成pytho ...
- C++ 写出这个数
题目如下: 读入一个正整数 n,计算其各位数字之和,用汉语拼音写出和的每一位数字. 输入格式: 每个测试输入包含 1 个测试用例,即给出自然数 n 的值.这里保证 n 小于 1. 输出格式: 在一行内 ...
- SpringIOC原理
IOC(DI):其实这个Spring架构核心的概念没有这么复杂,更不像有些书上描述的那样晦涩.java程序员都知道:java程序中的每个业务逻辑至少需要两个或以上的对象来协作完成,通常,每个对象在使用 ...
- Linux安装软件出错
1.Delta RPMs disabled because /usr/bin/applydeltarpm not installed. yum provides '*/applydeltarpm' # ...
- Redis图形管理 redis-browser
目录 一.介绍 二.部署 三.启动 监听单台 听多台 四.报错合集 一.介绍 redis-browser是redis的web端图形化管理工具.利用它可以查看和管理redis的数据,界面简洁,能和ral ...
- Python pyecharts绘制饼图
一.pyecharts绘制饼图语法简介 饼图主要用于表现不同类目的数据在总和中的占比.每个的弧度不是数据量的占比pie.add()方法的用法add(name, attr, value, radius= ...
- 【web】sqli-labs学习
第一页 1~4预备知识(基于错误的注入) 几个常用函数: 1. version()--MySQL 版本 2. user()--数据库用户名 3. database()--数据库名 4. @@dat ...
- /etc/resolv.conf文件中的search项作用;如何保持resolv.conf文件内容不被修改
/etc/resolv.conf文件中的search项作用 resolv.conf文件中有search项时,主机名解析规则顺序: DNS配置文件如下: # cat /etc/resolv.conf ; ...
- tomcat Address already in use: JVM_Bind
运行多个tomcat时,出现tomcat Address already in use: JVM_Bind这个错误,可以按照如下方式解决: 修改F:\tomcat20111101\apache-tom ...
- 13 - Vue3 UI Framework - 完善官网
为了提升用户体验,今天我们来对 jeremy-ui 官网做一个优化 返回阅读列表点击 这里 Markdown 解析支持 ️ 习惯用 markdown 语法编辑,所以我们增加项目源码对 markdown ...