<数据结构>由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二叉搜索树后序遍历序列
题目
随机推荐
- 大数据学习day24-------spark07-----1. sortBy是Transformation算子,为什么会触发Action 2. SparkSQL 3. DataFrame的创建 4. DSL风格API语法 5 两种风格(SQL、DSL)计算workcount案例
1. sortBy是Transformation算子,为什么会触发Action sortBy需要对数据进行全局排序,其需要用到RangePartitioner,而在创建RangePartitioner ...
- Postman 中 Pre-request Script 常用 js 脚本
1. 生成一个MD5或SHA1加密的字符串str_md5,str_sha1 string1 = "123456"; var str_md5= CryptoJS.MD5(string ...
- 【Linux】【Commands】trouble shooting命令详解目录
1. 简介 1.1. 最近看到阿里的运维招聘需要熟练掌握以下的命令,我就针对这几个命令做一下总结,有些命令我觉得别人总结的挺好了,我就不赘述了 1.2. 还有一些其他我觉得用得到的命令的用法会在第三部 ...
- UNIX基本命令
### 1. 必学命令 help [子命令] : 查看某一个具体的子命令的使用方法### 2. 常用命令 - cd path : 将当前路径切换到path路径 - pwd : 查看当前所在路径 - l ...
- 【Spring Framework】Spring入门教程(五)AOP思想和动态代理
本文主要讲解内容如下: Spring的核心之一 - AOP思想 (1) 代理模式- 动态代理 ① JDK的动态代理 (Java官方) ② CGLIB 第三方代理 AOP概述 什么是AOP(面向切面编程 ...
- Layui:select下拉框回显
一..需求场景分析 基于Thymeleaf模板下的layui下选框回显. 二.获得一个Layui标配的下拉框,我们需要在html中填写的内容如下 <div class="layui-f ...
- 【C/C++】日期问题/算法笔记/入门模拟
最近把算法竞赛入门经典的前半部分看完了,开始看算法笔记入门算法. 看了前半部分的例题,很多是算法竞赛入门经典中出现过的,但是感觉这本书写的更适合初学者,而且真的很像考试笔记,通俗易懂. //日期问题 ...
- 『与善仁』Appium基础 — 22、获取元素信息的操作(一)
目录 1.获取元素文本内容 (1)text()方法 (2)get_attribute()方法 (3)综合练习 2.获取元素在屏幕上的坐标 1.获取元素文本内容 (1)text()方法 业务场景: 进入 ...
- Android App加固原理与技术历程
App为什么会被破解入侵 随着黑客技术的普及化平民化,App,这个承载我们移动数字工作和生活的重要工具,不仅是黑客眼中的肥肉,也获得更多网友的关注.百度一下"App破解"就有529 ...
- 【web】sqli-labs学习
第一页 1~4预备知识(基于错误的注入) 几个常用函数: 1. version()--MySQL 版本 2. user()--数据库用户名 3. database()--数据库名 4. @@dat ...