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;
}

题后反思:数组树的不足

  1. 只有在表示完全二叉树的时候更方便:用数组表示非完全二叉树是所需要的附加操作不足可能比实现二叉链表树更加繁琐。
  2. 空间有限:数组不能开太大。
  3. 不方便用遍历操作,基本操作集合还没构建模板,要现场实现。

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); }
}

总结

  1. 都需要中序: X+中序
  2. X确定结点,中序确定左右子树位置
  3. 递归求解

<数据结构>由SearchTree的遍历序列确定树的更多相关文章

  1. 数据结构之 图论---基于邻接矩阵的广度优先搜索遍历(输出bfs遍历序列)

    数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历 Time Limit: 1000MS Memory limit: 65536K 题目描述 给定一个无向连通图,顶点编号从0到n-1,用广度优先搜索( ...

  2. PAT-1086(Tree Traversals Again)Java语言实现+根据中序和前序遍历构建树并且给出后序遍历序列

    Tree Traversals Again Tree Traversals Again 这里的第一个tip就是注意到非递归中序遍历的过程中,进栈的顺序恰好是前序遍历的顺序,而出栈的顺序恰好是中序遍历的 ...

  3. C++版 - 剑指offer 面试题24:二叉搜索树BST的后序遍历序列(的判断) 题解

    剑指offer 面试题24:二叉搜索树的后序遍历序列(的判断) 题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则返回true.否则返回false.假设输入的数组的任意两个 ...

  4. LeetCode---105. 从前序与中序遍历序列构造二叉树 (Medium)

    题目:105. 从前序与中序遍历序列构造二叉树 根据一棵树的前序遍历与中序遍历构造二叉树. 注意: 你可以假设树中没有重复的元素. 例如,给出 前序遍历 preorder = [3,9,20,15,7 ...

  5. 【PHP数据结构】完全二叉树、线索二叉树及树的顺序存储结构

    在上篇文章中,我们学习了二叉树的基本链式结构以及建树和遍历相关的操作.今天我们学习的则是一些二叉树相关的概念以及二叉树的一种变形形式. 完全二叉树 什么叫完全二叉树呢?在说到完全二叉树之前,我们先说另 ...

  6. 剑指Offer面试题:22.二叉搜索树的后序遍历序列

    一.题目:二叉搜索树的后序遍历序列 题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则返回true,否则返回false.假设输入的数组的任意两个数字都互不相同. 例如在下面 ...

  7. (剑指Offer)面试题24:二叉搜索树的后序遍历序列

    题目: 输入一个整数数组,判断该数组是不是某个二叉搜索树的后序遍历的结果,如果是则返回true,否则返回false. 假设输入的数组的任意两个数字都互不相同. 思路: 根据二叉搜索树的后序遍历特点,很 ...

  8. 1048 图的宽度优先遍历序列 c语言

    描述 图(graph)是数据结构 G=(V,E),其中V是G中结点的有限非空集合,结点的偶对称为边(edge):E是G中边的有限集合.设V={0,1,2,……,n-1},图中的结点又称为顶点(vert ...

  9. 基于visual Studio2013解决面试题之0208二叉搜索树后序遍历序列

     题目

随机推荐

  1. js正则表达式之密码强度验证

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. 爬虫系列:存储 CSV 文件

    上一期:爬虫系列:存储媒体文件,讲解了如果通过爬虫下载媒体文件,以及下载媒体文件相关代码讲解. 本期将讲解如果将数据保存到 CSV 文件. 逗号分隔值(Comma-Separated Values,C ...

  3. 连接查询条件在on后面和条件在where后面

    emp表结构如下: dept表结构如下: 内连接 条件语句放在on 后面和 where 结果对于inner join结果是一样的 但对于left join 结果会产生不一样 这种现象也比较好理解,如果 ...

  4. OSGi系列 - 使用Eclipse查看Bundle源码

    使用Eclipse开发OSGi Bundle时,会发现有很多现成的Bundle可以用.但如何使用这些Bundle呢?除了上网搜索查资料外,阅读这些Bundle的源码也是一个很好的方法. 本文以org. ...

  5. Spring事务隔离级别和传播特性(转)

    相信每个人都被问过无数次Spring声明式事务的隔离级别和传播机制吧!今天我也来说说这两个东西. 加入一个小插曲,一天电话里有人问我声明式事务隔离级别有哪几种,我就回答了7种,他问我Spring的版本 ...

  6. 【Java基础】ArrayList初始化操作

    要用60个零初始化列表,请执行以下操作: List<Integer> list = new ArrayList<Integer>(Collections.nCopies(60, ...

  7. 解决git push报错error: failed to push some refs to 的问题

    这个问题发生的背景一般是: 想把自己本地的某个项目关联到远程仓库并推送上去,接着他会做如下操作: 本地项目->远程创建仓库->本地关联远程->推送最新代码 最后一个步骤发生问题: 那 ...

  8. TCP协议三步挥手与四步挥手

    关于TCP协议 TCP(Transmission Control Protocol, 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议.与之对应的是UDP(User Datagram ...

  9. 在vue3中使用router-link-active遇到的坑

    在使用 router-link-active 设置链接激活时CSS类名时,发现在例如 /member/order 和 /member/order/:id 这两个都包含 /member/order的路由 ...

  10. Mysql主从复制参数详解

    目录 一.简介 二.例子 同步 修改 三.参数 一.简介 change master to配置和改变slave服务器用于连接master服务器的参数,以便slave服务器读取master服务器的bin ...