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. 零基础学习java------30---------wordCount案例(涉及到第三种多线程callable)

    知识补充:多线程的第三种方式 来源:http://www.threadworld.cn/archives/39.html 创建线程的两种方式,一种是直接继承Thread,另外一种就是实现Runnabl ...

  2. 零基础学习java------day14-----泛型,foreach,可变参数,数组和集合间的转换,Set,Map,

    1.泛型(jdk1.5以后出现) https://www.cnblogs.com/lwbqqyumidi/p/3837629.html#!comments (1)为什么要用泛型? 限制集合,让它只能存 ...

  3. JavaIO——内存操作流、打印流

    我们之前所做的都是对文件进行IO处理,实则我们也可以对内存进行IO处理.我们将发生在内存中的IO处理称为内存流. 内存操作流也可分为两类:字节内存流和字符内存流. (1)ByteArrayInputS ...

  4. Mysql不锁表备份之Xtrabackup的备份与恢复

    一.Xtrabackup介绍 MySQL冷备.热备.mysqldump都无法实现对数据库进行增量备份.如果数据量较大我们每天进行完整备份不仅耗时且影响性能.而Percona-Xtrabackup就是为 ...

  5. VSCode上发布第一篇博客

    在VSCode上发布到博客园的第一篇博客 前段时间在VSCode安装好插件WriteCnblog,多次检查writeCnblog configuration配置信息也是完全正确的,但是一直没能在VSC ...

  6. bootstrapTable频繁向后台接口发请求

    当bootstrapTable出现这样的问题,是因为查询到的数据行数为空,而后台返回的总行数又不为0时,就会疯狂地往接口发请求

  7. 联盛德 HLK-W806 (七): 兼容开发板 LuatOS Air103

    目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...

  8. 01 - Vue3 UI Framework - 开始

    写在前面 一年多没写过博客了,工作.生活逐渐磨平了棱角. 写代码容易,写博客难,坚持写高水平的技术博客更难. 技术控决定慢慢拾起这份坚持,用作技术学习的阶段性总结. 返回阅读列表点击 这里 开始 大前 ...

  9. C# .exe和.dll文件图标资源提取工具

    Windows 可执行文件(.exe)和动态库文件(.dll)图标资源提取工具 GitHub 功能 图标资源预览 图标资源导出(仅支持导出 PNG 格式) 代码 获取图标资源使用了 Win32 API ...

  10. 如何在子线程中更新UI

    一:报错情况 android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that creat ...