C++先序和中序确定二叉树
思考:如何才能确定一棵树?
结论: 通过中序遍历和先序遍历可以确定一个树
通过中序遍历和后续遍历可以确定一个树
通过先序遍历和后序遍历确定不了一个树。
单独先序遍历:能求解根,但不能求解左子树什么时候结束、右子树什么时候开始。
根据先序和中序结果画树
算法
1、通过先序遍历找到根结点A,再通过A在中序遍历的位置找出左子树,右子树
2、在A的左子树中,找左子树的根结点(在先序中找),转步骤1
3、在A的右子树中,找右子树的根结点(在先序中找),转步骤1
根据如下遍历结果创建二叉树:
先序遍历结果:ABDHKECFIGJ
中序遍历结果:HKDBEAIFCGJ
代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>typedef struct Node{Node *lchild;Node *rchild;char c;
}Node,*Tree;//静态内存分配数组
//int loc;//对原始代码进行了改进!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!char str1[30];
char str2[30];Node *createNode(){
// Tree[loc].lchild = Tree[loc].rchild=NULL;
// return &Tree[loc++];Tree node = (Tree)malloc(sizeof(Node));if (node) {node->lchild=node->rchild=NULL;return node;}else{printf("无法分配节点");exit(0);}}
//后序遍历算法
void postOrder(Node *T){if (T->lchild!=NULL) {postOrder(T->lchild);}if (T->rchild!=NULL) {postOrder(T->rchild);}printf("%c",T->c); //这里要用“%c”,因为就输出一个字符, 不能用“%s”, 它是输出字符串}
//先序遍历
void preOrder(Tree T){printf("%c",T->c); //这里要用“%c”,因为就输出一个字符, 不能用“%s”, 它是输出字符串if (T->lchild!=NULL) {preOrder(T->lchild);}if (T->rchild!=NULL) {preOrder(T->rchild);}
}
//中序遍历
void midOrder(Tree T){if (T->lchild!=NULL) {midOrder(T->lchild);}printf("%c",T->c); //这里要用“%c”,因为就输出一个字符, 不能用“%s”, 它是输出字符串if (T->rchild!=NULL) {midOrder(T->rchild);}}Node * build(int s1,int e1,int s2,int e2){//根据前序遍历序列str1和中序遍历序列str2构建树,并返回树的根节点,Node * ret = createNode();//构建根节点,ret->c = str1[s1];int rootIdx;for (int i = s2; i<=e2;i++ ) {if (str2[i]==str1[s1]) {rootIdx = i;//在中序遍历序列中找到根节点的下标;break;}}if(rootIdx!=s2){//说明左子树不为空ret->lchild = build(s1+1, s1+(rootIdx-s2), s2, rootIdx-1);}if (rootIdx!=e2) {//说明右子树不为空ret->rchild=build(s1+(rootIdx-s2)+1, e1, rootIdx+1, e2);}return ret;
}
//建立一颗二叉树,前序
Node *buildTree(){//输入字符建立二叉树,遇到#便设置这个节点为空Node *root =(Tree)malloc(sizeof(Node));char a;scanf("%c",&a);if (a=='#') {root = NULL;}else{root->c = a;root->lchild = buildTree();root->rchild = buildTree();}return root;
}
//求树的高度
int high_Tree(Tree T){if (T==NULL) {return 0;}else{int lh = high_Tree(T->lchild);int rh = high_Tree(T->rchild);return lh>rh?lh+1:rh+1;}}
int main() {while(scanf("%s",str1)!=EOF){scanf("%s",str2);int L1 = strlen(str1);int L2 = strlen(str2);Node * T = build(0, L1-1, 0, L2-1);postOrder(T);printf("%d\n",high_Tree(T));printf("\n");}return 0;
}
源代码二:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;; const int N=31; typedef struct BitNode
{ char value; BitNode *lchild,*rchild;
}BitNode,*BiTree; /* *&代表什么? //https://zhidao.baidu.com/question/2266744263935050308.html这是C++的语法写法,&在形参中表示“引用”实参,
LNode * &lst ; 中LNode * 是个整体,表示变量类型是LNode类指针, &lst中的&表明引用实参,即代表实参的一个别名。
标准C是不支持这种写法的。追问&不是取地址符吗? 引用参数是什么意思追答&在变量定义区,表示引用,要注意它的用法,
&在变量操作区,表示取地址符,如:int x=10, *p=&x ; //这里&作用在x上, 是取地址符
int &x ; //引用是C++引入的一个新特性,你要学的不是C++,则上述代码你是搞不懂的。 这里的&就表示引用。 一般这种形式会在形参中出现。LNode * &lst ; 中LNode * 是个整体,表示变量类型是LNode类指针, &lst中的&表明引用实参,即代表实参的一个别名。 操作引用变量就相当于操作实参变量*/void CreatTree(BitNode* &root,char *pre,int l1,int r1,char *in,int l2,int r2)
{ if(l1<=r1&&l2<=r2) { int key=pre[l1]; int midIndex=-1; for(int i=l2;i<=r2;i++) { if(in[i]==key) { midIndex=i; break; } } root=(BitNode *)malloc(sizeof(BitNode)); root->value=key; root->lchild=NULL; root->rchild=NULL; int llen=midIndex-l2; CreatTree(root->lchild, pre, l1+1, l1+llen, in, l2, midIndex-1); CreatTree(root->rchild, pre, l1+llen+1, r1, in, midIndex+1, r2); }
} void postOrderTraverse(BitNode *&root)
{ if(root->lchild) postOrderTraverse(root->lchild); if(root->rchild) postOrderTraverse(root->rchild); printf("%c",root->value);
} int main()
{ char pre[N],in[N]; while(scanf("%s",pre)!=EOF) { scanf("%s",in); int len1=strlen(pre); int len2=strlen(in); BitNode *root=NULL; CreatTree(root,pre,0,len1-1,in,0,len2-1); postOrderTraverse(root); printf("\n"); } return 0;
}
C++先序和中序确定二叉树相关推荐
- 给定二叉树先序、中序遍历序列,求后序遍历
给定一个二叉树的前序遍历和中序遍历的序列,输出对应这个二叉树的后续遍历序列. 输入描述: 输入为一行. 两个字符串,分别表示二叉树的前序遍历和中序遍历结果,用空格分隔.保证数据合法 输出描述: 对应输 ...
- 常考数据结构与算法:实现二叉树先序,中序和后序遍历
题目描述 分别按照二叉树先序,中序和后序打印所有的节点. 输入 {1,2,3} 返回值 [[1,2,3],[2,1,3],[2,3,1]] import java.util.ArrayList;cla ...
- 分别用递归和非递归方式实现二叉树先序、中序和后序遍历(java实现)
分别用递归和非递归方式实现二叉树先序.中序和后序遍历 用递归和非递归方式,分别按照二叉树先序.中序和后序打印所有的节点.我们约定:先序遍历顺序 为根.左.右;中序遍历顺序为左.根.右;后序遍历顺序为左 ...
- 数据结构-简单实现二叉树的先序、中序、后序遍历(java)
第一步:创建一颗二叉树 public class Node { private int data;//数据域private Node leftNode;//左孩子private Node rightN ...
- 算法练习day10——190328(二叉树的先序、 中序、 后序遍历, 包括递归方式和非递归方式、找到一个节点的后继节点、二叉树的序列化和反序列化)
1.实现二叉树的先序. 中序. 后序遍历, 包括递归方式和非递归方式 1.1 访问节点的顺序 节点访问顺序如下图所示: 访问顺序:1 2 4 4 4 2 5 5 5 2 1 3 6 6 6 3 7 7 ...
- 【算法学习笔记】二叉树的基本操作实现和应用举例,根据先序与中序遍历建立二叉树的实现
基本操作 给某结点插入一个左孩子 删除二叉树中某结点的左子树 根据先序与中序遍历建立二叉树 应用举例 查找数据元素 二叉链表存储结构 统计叶结点的数目 基本操作 通常有:建立空二叉树.生成以X为根节点 ...
- [转载]二叉树先序、中序、后序三种遍历的非递归算法
本贴给出二叉树先序.中序.后序三种遍历的非递归算法,此三个算法可视为标准算法. 1.先序遍历非递归算法 #define maxsize 100 typedef struct { Bitree Elem ...
- 二叉树的先序、中序、后序遍历
记得有次被别人问起二叉树的先序遍历,竟然不清楚?当然读书的时候是知道的,工作后有点忘了,只知道它是利用栈递归遍历的,至于这里的先序的"先",到底指的是先遍历左子树还是先遍历根节点给 ...
- 先序,中序,后序线索二叉树
//后序线索,这种方法不容易想到 #include<iostream> #include<cstring> #include<cstdio> #include< ...
- Uva536 Tree Recovery二叉树重建(先序和中序确定二叉树,后序输出)
题目大意:给定二叉树先序和中序遍历,输出二叉树后序遍历. 方法:将英文字母映射为数字,利用数组存储,先序第一个节点是父节点,然后再从中序遍历中找到位置.注意边界.代码也很简单一次ac. #includ ...
最新文章
- 规则管理_看板管理的五大使用规则
- LeetCode实战:除自身以外数组的乘积
- 7月书讯:看风景的人
- JVM经常使用的调优參数
- 如何做618数据复盘?你需要掌握这8大思路
- 数据结构与算法之选择排序图文详解及代码 (C++实现)
- 程序员Web面试之JSON
- mybatis 返回 插入的主键
- java利用htmlparser得到网页html内容
- oracle与raw device
- 计算机编程常用指令,加工中心几个常用指令的编程技巧
- sqlite3 交叉编译出现configure: error: C compiler cannot create executables
- Android反编译与防止反编译
- 【云栖精选】6篇深度!解除MySQL数据同步疑惑+Docker技术示例
- 如何在知网直接下载PDF格式的硕博士论文
- C语言typedef用法详解
- adb远程(异地)连接实现投屏
- vue 时间轴:效果图
- Python 小型项目大全 36~40
- 行内和块级元素区别?如何让行内元素设置宽高?
热门文章
- php考勤系统微信小程序
- Java数据结构与算法 一
- eplan连接定义点不显示_EPLAN操作命令之线色设置
- wamp打开php,wamp本地php环境开启GD库教程
- Cook-Torrance/ Ward反射方程
- 组建一个网络需要哪些网络设备和安全设备呢?
- python xlwt安装linux_Linux安装Python xlrd、xlwt、xlutils模块
- ️ 后羿采集器——最良心的爬虫软件
- textarea统计字数
- 数据挖掘:实用案例分析 下载_萌低龄,超实用“萌系”呈现技巧及设计案例分析...