下面三种序列可以唯一的构造唯一的一棵二叉树:

前序序列和中序序列构造二叉树

后序序列和中序序列构造二叉树

层次遍历序列和中序遍历序列构造二叉树

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define MaxSize 10
typedef struct BTNode{char data;struct BTNode *lchild,*rchild;
}BTNode,*BiTree;//根据前序序列,中序序列建造一棵二叉树
//参数含义:pre[]前序序列  in[]中序序列
//          L1  R1用于指定pre[]的搜索区域
//          L2  R2用于指定in[]的搜索区域
BiTree createBiTree(char pre[],char in[],int L1,int R1,int L2,int R2){if(L1>R1){return NULL;//递归出口 }BTNode *s =(BTNode*)malloc(sizeof(BTNode));s->lchild =NULL;s->rchild =NULL;s->data=pre[L1];int i;//根据中序序列的特性,元素左边的元素属于该节点的左孩子序列,右边则是右孩子序列 for(i=L2;i<=R2;i++){if(pre[L1]==in[i]) break;//在中序序列找到该元素 }s->lchild=createBiTree(pre,in,L1+1,L1+i-L2,L2,i-1);//递归 s->rchild=createBiTree(pre,in,L1+i-L2+1,R1,i+1,R2); return s;
}
//根据后序中序建立二叉树
BiTree createBiTree2(char post[],char in[],int L1,int R1,int L2,int R2){if(L1>R1){return NULL;//递归出口 }BTNode *s =(BTNode*)malloc(sizeof(BTNode));s->lchild =NULL;s->rchild =NULL;                   s->data=post[R1];//后序序列最后一个节点为根节点 int i;//根据中序序列的特性,元素左边的元素属于该节点的左孩子序列,右边则是右孩子序列 for(i=L2;i<=R2;i++){if(post[R1]==in[i]) break;//在中序序列找到该元素 }//递归 面试官:为什么要减去L2? 答:递归传下去的是整个数组,需要根据参数找到递归出口,-L2是缩小查找范围 s->lchild=createBiTree2(post,in,L1,L1+i-L2-1,L2,i-1);s->rchild=createBiTree2(post,in,L1+i-L2,R1-1,i+1,R2); return s;
}
//该函数用于在中序序列中找到key,返回其位置
//参数含义:in[]:中序序列  key:所要查找元素 L,R:查找范围
int serach(char in[],char key,int L,int R){for(int i=L;i<=R;i++){if(in[i]==key) return i;}return -1;
}//因为在中序序列元素的左面的元素在层次遍历序列中并不连续,所以需要用子序列函数将并不连续的序列连续起来
//为什么要连续起来?因为需要连续起来才能和中序序列构造出二叉树
//思路:在中序序列里查找到一个范围,从这个范围里遍历元素,在层次遍历序列里找该元素
//参数含义:sublevel[]:存放子序列数组  level[]:层次遍历序列  in[]:中序序列 n:level层次序列长度 L,R:查找范围
void getSubLevel(char sublevel[],char level[],char in[],int n,int L,int R){int k=0;for(int i=0;i<n;i++){if(serach(in,level[i],L,R)!=-1)sublevel[k++]=level[i]; }
}
//由中序序列和层次遍历序列构造二叉树
BiTree createBiTree3(char level[],char in[],int n,int L,int R){if(L>R) return NULL;BTNode *s =(BTNode*)malloc(sizeof(BTNode));s->lchild =NULL;s->rchild =NULL;                   s->data=level[0];int i=serach(in,level[0],L,R);//找到i便可以确定左右子树答大小 int LN=i-L; char LLevel[LN];int RN=R-i; char RLevel[RN];getSubLevel(LLevel,level,in,n,L,i-1);//得到子序列 getSubLevel(RLevel,level,in,n,i+1,R);s->lchild=createBiTree3(LLevel,in,LN,L,i-1);//用子序列递归 s->rchild=createBiTree3(RLevel,in,RN,i+1,R); return s;
}
void visit(BiTree T) {printf("%c  ",T->data);
}
//前序遍历
void PreOrder(BiTree T){if(T!=NULL){visit(T);//根 PreOrder(T->lchild);//左 PreOrder(T->rchild);//右 }
}
//中序遍历
void InOrder(BiTree T){if(T!=NULL){InOrder(T->lchild);visit(T);InOrder(T->rchild);}
}
//后序遍历
void PostOrder(BiTree T){if(T!=NULL){PostOrder(T->lchild);PostOrder(T->rchild);visit(T);}
}
//层次遍历
void level(BiTree T){if(T!=NULL){int front=0;int rear=0;BiTree queue[MaxSize];BiTree p;p=T;rear=(rear+1)%MaxSize;queue[rear]=p;while(rear!=front){front=(front+1)%MaxSize;p=queue[front];visit(p); if(p->lchild!=NULL){rear=(rear+1)%MaxSize;queue[rear]=p->lchild; } if(p->rchild!=NULL){rear=(rear+1)%MaxSize;queue[rear]=p->rchild;}}}
}
int main(){char c[]="ABDECFGH";//前序序列 char d[]="DBEACGFH";//中序序列 char p[]="DEBGHFCA";//后序序列 char l[]="ABCDEFGH";//层次遍历序列 BTNode *r=createBiTree(c,d,0,7,0,7);BTNode *r2=createBiTree2(p,d,0,7,0,7);BTNode *r3=createBiTree3(l,d,8,0,7); printf("前序序列为:"); PreOrder(r);printf("\n");printf("后序序列为:");PostOrder(r2);printf("\n");printf("中序序列为:"); InOrder(r3);printf("\n");printf("层次遍历为:");level(r3); printf("\n");} 

代码运行截图:

由序列确定二叉树:前序序列和中序序列构造二叉树 后序序列和中序序列构造二叉树 层次遍历序列和中序遍历序列构造二叉树 代码实现(c语言)相关推荐

  1. ppt录制宏_Word中录制宏,学会后成大神

    Word中录制宏,学会后成大神 Word是日常工作.生活不可避免的工具,掌握word的一些技巧,可以提高效率,让工作事半功倍,下面由办公吧(offices8.com)整理的如何在word中使用宏. 这 ...

  2. Word中录制宏,学会后成大神

    Word中录制宏,学会后成大神 Word是日常工作.生活不可避免的工具,掌握word的一些技巧,可以提高效率,让工作事半功倍,下面由办公吧(offices8.com)整理的如何在word中使用宏. 这 ...

  3. 【中序、后序遍历序列】【前序、中序遍历序列】构造二叉树

    前置知识 第1点:每一个节点都可以看作一棵树的根节点. 第2点:掌握前序.中序.后序遍历顺序.前序遍历:根左右,中序遍历:左根右,后序遍历:左右根. 第3点:掌握双指针或者说滑动窗口,窗口所承载的是左 ...

  4. 【C语言】二叉树前序中序后序遍历详解!!!内附算法好题初阶(每日小细节021)

    二叉树三种遍历方式时刻牢记,所谓的前中后就是根的位置 前序:根->左子树->右子树 中序:左子树->根->右子树 后序:左子树->右子树->根 每日小细节新增算法好 ...

  5. 二叉树前序、中序、后序遍历非递归写法的透彻解析

    前言 在前两篇文章二叉树和二叉搜索树中已经涉及到了二叉树的三种遍历.递归写法,只要理解思想,几行代码.可是非递归写法却很不容易.这里特地总结下,透彻解析它们的非递归写法.其中,中序遍历的非递归写法最简 ...

  6. 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。

    输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树. 假设输入的前序遍历和中序遍历的结果中都不含重复的数字. 例如输入前序遍历序列{1, 2, 4, 7, 3, 5, 6, 8}和中序遍历序{ ...

  7. 二叉树前序中序,后序中序,公共最近祖先的实现

    二叉树前序中序,后序中序,公共最近祖先的实现 注释中详细介绍了算法,故不再赘述. 无论是前序还是后序,一个节点的左子树和右子树都是可以看做是分开的,有一定规律可循,故可用递归进行实现. #includ ...

  8. 二叉树前序遍历、中序遍历、后序遍历、层序遍历的直观理解

    0. 写在最前面 希望大家收藏: 本文持续更新地址:https://haoqchen.site/2018/05/23/go-through-binary-tree/ 复习到二叉树,看到网上诸多博客文章 ...

  9. 二叉树——前序和中序得到后序

    由二叉树的前序和中序如何得到二叉树的后序呢?要给出答案,首先得明白什么是前序.中序.后序. 二叉树前序:遍历顺序为,根节点.左子树.右子树:中序:遍历顺序为,左子树.根节点.右子树:后序:遍历顺序为, ...

  10. 序列化和反序列化二叉树 -----前序,中序,后序,层序

    目录 一.序列化和反序列化 1.什么是序列化和反序列化 二.前序遍历 1.序列化 1.问题分析 2.代码实现 2.反序列化 1.问题分析 2.代码实现 三.后序遍历 1.序列化 1.思路分析 2.代码 ...

最新文章

  1. Redis 高负载排查记录
  2. html display布局,Web布局:display属性
  3. 生成对抗网络学习笔记4----GAN(Generative Adversarial Nets)的实现
  4. 【JZOJ3236】矮人排队
  5. [转]Shell中脚本变量和函数变量的作用域
  6. 在50亿信息泄露事件面前,Struts 2 漏洞和CIA泄密都是小事 | 宅客周刊
  7. QT的QJSValueIterator类的使用
  8. Linux 7 cmake:curses library not found
  9. html制作柱状图教程,基于Echarts的HTML5 Canvas折线图柱状图DEMO演示
  10. pygame的最小系统
  11. ltrim函数_数据分析常用Excel函数
  12. linux7ip路由,Centos7源地址访问路由(双IP双网关配置)
  13. KMP模式匹配算法程序(Python,C++,C)
  14. mysql数据库操作语句整合
  15. hsqldb mysql_hsqldb简单使用总结
  16. 隔空投送怎么用「详细教程」
  17. 【预测模型】基于遗传算法优化最小二乘支持向量机lssvm实现数据预测matlab代码
  18. Processing绘制星空-1-随机生成静态星星
  19. python实现word自动化操作
  20. Android Studio模拟器AndroidWifi连接成功但无法访问网络问题

热门文章

  1. 《牧羊少年的奇幻之旅》-保罗 柯艾略
  2. java摇号_java语言实现一个摇号系统,但是可以内部设定中奖名单这个怎么实现?...
  3. 希尔伯特到解析信号,再到复包络
  4. 最全总结---36种MySQL时间函数
  5. xcodebuild命令
  6. spring 定时器,时间设置
  7. 如何查看linux内核版本
  8. Matlab-初级教程-系列1:matlab之入门教学视频-3 数组和矩阵分析3
  9. 雨听 | 英语学习笔记(七)~作文范文:学生退学
  10. 数据脱敏(Data Masking)学习