二叉树的前序、中序、后序遍历与创建

#include <iostream>
#include <string>
#include <stack>
using namespace std;
struct node;
typedef node *pNode;
struct node {
     char data;
     pNode left, right;
};
string line;
string::iterator it;
// 前序扩展序列建立二叉树  
void plant(pNode &root)
{
     if (it == line.end())
         return;
     char data = *it++;
     if (data == '/')
         root = NULL;
     else {
         root = new node();
         root->data = data;
         plant(root->left);
         plant(root->right);
     }
}
// 先序遍历  
void pre_order(pNode root)
{
     stack<pNode> s;
     while (root != NULL || !s.empty())
     {
         if (root != NULL) {
             cout << root->data << " ";
             s.push(root);
             root = root->left;
         } else {
             root = s.top();
             s.pop();
             root = root->right;
         }
     }
}
// 中序遍历  
void in_order(pNode root)
{
     stack<pNode> s;
     while (root != NULL || !s.empty())
     {
         if (root != NULL) {
             s.push(root);
             root = root->left;
         } else {
             root = s.top();
             s.pop();
             cout << root->data << " ";
             root = root->right;
         }
     }
}
// 压栈的参数类型,包括局部变量和行号  
struct stack_arg {
     stack_arg(pNode _root, int _line)
     : root(_root), line(_line) { }
     pNode root;
     int line;
};
// 后序遍历  
void post_order(pNode root)
{
     stack<stack_arg> s;
     s.push(stack_arg(root, 1));
     while (!s.empty())
     {
         switch (s.top().line) {
         case 1:
             if (s.top().root == NULL)
                 s.pop();
             else
                 s.top().line = 2;
             break;
         case 2:
             s.top().line = 3;  
             s.push(stack_arg(s.top().root->left, 1));
             break;
         case 3:
             s.top().line = 4;
             s.push(stack_arg(s.top().root->right, 1));
             break;
         case 4:
             cout << s.top().root->data << " ";
             s.pop();
             break;
         }
     }
}
int main()
{
     cin >> line;
     it = line.begin();
     pNode root = NULL;
     plant(root);
     cout << "先序遍历" << endl;  
     pre_order(root);
     cout << endl;
     cout << "中序遍历" << endl;  
     in_order(root);
     cout << endl;
     cout << "后序遍历" << endl;  
     post_order(root);
     cout << endl;
     system("pause");
     return 0;
}
/*
input
     ABDI//J//EK//LQ///CFM//N//GO//P//
output
     先序遍历:
     A B D I J E K L Q C F M N G O P
     中序遍历
     I D J B K E Q L A M F N C O G P
     后序遍历  
     I J D K Q L E B M N F O P G C A

image

 

//
知树的前序遍历,后序遍历,怎么求中序遍历?
通过对同一棵二叉树三种遍历方式的分析,概括出由前序、中序或由中序、后序遍历结果快速还原二叉树的方法。 
二叉树是最为常用的数据结构,它的实际应用非常广泛。二叉树的遍历方式有三种,前序遍历、中序遍历、后序遍历。先序遍历的顺序为:NLR,即先根结点,然后左子树、右子树;中序遍历顺序为:LNR先左子树,然后根结点、右子树;后序遍历顺序为:LRN先左子树、然后右子树、根结点。由前序和中序遍历、由中序和后序遍历序列可以唯一确定一棵二叉树,而由前序和后序遍历序列不能唯一确定一棵二叉树。 
  二叉排序树对二叉树作了进一步的限定:根结点的权值大于(或小于)左子树中所有结点的权值;根结点的权值小于(或大于)其右子树中所有结点的权值。 
  那么如何根据三种遍历序列之间的关系及二叉排序树来快速还原一棵二叉树?下面以二叉树的前序和中序遍历序列为基础,利用二叉排序树的性质,给出快速还原二叉树的方法。 
  1由给定前序和中序序列或中序和后序序列还原二叉树的方法 
  例:前序序列:ABDECFGH 中序序列:DEBACGFH (后序序列:EDBGHFCA) 
  (1)给中序序列中的每个结点从小到大、从左到右赋以权值,如下: 
  D(1)E(2)B(3)A(4)C(5)G(6)F(7)H(8) 
  (2)还原时读入的序列为前序序列,从左到右依次读入序列中的各个结点值和相应的权值;  
  (3)由读入的序列,根据第1)步中给定的权值按照二叉排序树的构造规则构造二叉排序树。第一个读入的结点为根结点,其他结点分别为左右子树中的结点。设根结点为TT,权值为NN,当前读入结点为SS,权值为MM,若MM
  (4)将SS插入到TT的左子树或右子树的过程中,仍然遵循3)中的规则,直至左子树或右子树为空时止。 
  (5)读入序列结束时,二叉树还原成功。 
6)对于由中序序列和后序序列还原二叉树是,读入的序列为后序序列,从右向左读入,构造规则同上。还原结果与上述结果完全一致。

2还原方法的确定依据 
  二叉树遍历过程中,在中序序列中,根结点的左子树中的所有结点都在根结点的左侧,根结点的右子树中的所有结点都在根结点的右侧,这个特点恰好与二叉排序树具有相同的性质;在读入序列时,前序序列则从左向右读,这恰好与遍历二叉树的顺序相同;后序序列从右向左读,则按照根结点、右子树、左子树的顺序还原。 
  (1)设二叉树共有N个结点(N为大于1的正整数),我们按照还原方法给中序序列中的这N个结点分别赋予权值1,2…N,设根结点的权值为M(1
  (2)由二叉树的遍历规则可知,权值为1,2…M-1的结点为根结点的左子树中的结点,而权值为M+1,…N的结点为根结点的右子树中的结点。 
  (3)将这N个结点划分成3个子集AA=(1,2…M-1)BB=(M)CC=(M+1,…N),由于前序序列第一个读入的结点必定为二叉根的根结点,所以BB为根结点,AA集为左子树,CC集为右子树。 
  (4)同理不断读入前序序列中的结点,依次递归还原BB对应的左子树和CC对应的右子树,最后将三棵子树合并成以BB为根结点、AA的根结点为BB的左子树、CC的根结点为BB的右子树的一棵二叉排序树。 
  (5)同理可以得出,由中序序列和后序序还原二叉树的规则也成立。 
  (6)在还原过程中,读入序列的顺序也遵循也先根结点,后子树的规律。 
  3总结 
  在二叉树的一些应用中,如平衡二叉树、红黑树等,常常要观察二叉树的形态,对其进行判断并调整。根据遍历序列和二叉排序树的性质快速还原出二叉树对于研究相关的问题有很大的帮助。

 

上面可以得出前序扩展序列 ABD/E///C//FG//H

image

后序为 ED##B###G##HFCA

 

void PreCreate(Node* p)

{

if(line == end)

   return;

  if(line == “/”)

      p = NULL;

else{

   p = new NOde();

   p->data = line;

   PreCreate(p->Left);

    PreCreate(p->Right);

}

}

本文转自博客园知识天地的博客,原文链接:二叉树的前序、中序、后序遍历与创建,如需转载请自行联系原博主。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/279008.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

flex-2

1、 2、 justify&#xff1a;整理版面 3、 4、归纳 justify-content&#xff1a;flex-start&#xff08;默认&#xff09;、center、flex-end 下面还会提到剩下的两种项目在主轴上对齐方式&#xff1a; space-between:两端对齐&#xff08;项目间距离相等&#xff09; space-ar…

TextInput

TextInput /** TextInput 是一个允许用户在应用中通过键盘输入文本的基本组件* 本组件的属性提供了多种特性的配置,如自动完成,自动大小写,占位文字,键盘类型等* 常用:* placeholder 占位符* value 输入框的值* password 是否密文输入* editable 是否可编辑* retureKeyType …

如何使用oracle查询,oracle 表查询

Oracle 的 oracle 表查询通过scott用户下的表来演示如何使用select语句&#xff0c;接下来对emp、dept、salgrade表结构进行解说。emp 雇员表字段名称 数据类型 是否为空 备注-------- ----------- -------- --------EMPNO NUMBER(4) 员工编…

火狐标签在中间_在Firefox中保留未使用的标签

火狐标签在中间If you have a lot of content heavy webpages open in Firefox, it soon adds up on memory usage. The BarTab extension puts unused tabs on hold and keeps them unloaded until you are ready to access them. 如果您在Firefox中打开了大量内容繁重的网页&…

[CQOI2012]模拟工厂 题解(搜索+贪心)

[CQOI2012]模拟工厂 题解(搜索贪心) 标签&#xff1a;题解 阅读体验&#xff1a;https://zybuluo.com/Junlier/note/1327574 链接题目地址&#xff1a;洛谷P3161 BZOJ P2667 这个题练一练综合思想还是不错的。。。&#xff08;然而蒟蒻不会啊&#xff09; 做法 肯定是在能完成某…

上传文件的input问题以及FormData特性

1.input中除了type"file"还要加上name"file"&#xff0c;否则$_FILES为空&#xff0c;input的name值就是为了区分每一个input的 2.var formdata new FormData($("#form")[0]); 或者var formdata new FormData(document.getElementById("f…

iphone手机备忘录迁移_如何在iPhone和iPad上使用语音备忘录

iphone手机备忘录迁移Whether you’re recording a voice message as a reminder of that million dollar idea or catching a snippet of a new song you know you’ll forget, the iPhone and iPad’s Voice Memos app is the perfect tool. 无论您是录制语音消息来提醒这一百…

php 执行文件tar打包,利用tar for windows对大量文件进行快速打包

近期将某些网站换服务器&#xff0c;由于网站数量巨大&#xff0c;加上附件和静态页&#xff0c;文件数量异常多&#xff0c;考虑先打包然后直接传过去。起初尝试用winrar打包&#xff0c;但是发现即使选择”仅储存”速度仍然慢到无法接受&#xff0c;后来想到了tar&#xff0c…

DDD~领域事件中使用分布式事务

对于一个聚合来说&#xff0c;它可能会被附加很多事件&#xff0c;这里我们叫它领域事务&#xff0c;因为一个聚会我们可以把它理解成一个领域&#xff0c;一个业务。对于领域事件不清楚的同学可以看看我的这篇文章《DDD~领域事件与事件总线》&#xff0c;里面有详细的说明&…

如何在PowerPoint中制作打字机或命令行动画

Adding quirky animations to your Microsoft PowerPoint presentation gives your slideshow a little extra life. Not only will adding a typewriter or command line animation entertain your audience, but it will also keep them focused on the text. 在您的Microsof…

oracle中spool卸数,数据卸载--spool的使用

&#xfeff;&#xfeff;引言在项目中&#xff0c;我们经常会遇到数据的卸载、装载需求。卸载就是需要将数据从数据库中导入到文本文件中的需求&#xff0c;这样的方法有很多&#xff0c;比较常用的就是spool命令。装载就是需要将数据从文本文件中导入到数据库中。方法也有很多…

Objective-C中的@property

1.property是什么 Property是声明属性的语法&#xff0c;它可以快速方便的为实例变量创建存取器&#xff0c;并允许我们通过点语法使用存取器。 存取器&#xff08;accessor&#xff09;&#xff1a;指用于获取和设置实例变量的方法。用于获取实例变量值的存取器是getter&#…

Linux基础命令---findfs

findfs 查找指定卷标或者UUID的文件系统对应的设备文件。findfs将搜索系统中的磁盘&#xff0c;寻找具有标签匹配标签或与UUID相等的文件系统。如果找到文件系统&#xff0c;文件系统的设备名称将打印在stdout上。 此命令的适用范围&#xff1a;RedHat、RHEL、Ubuntu、CentOS、…

canvas 平滑运动_什么是电视上的运动平滑?人们为什么讨厌它?

canvas 平滑运动Willy Barton/Shutterstock.com威利巴顿/Shutterstock.comIf you’ve just bought a new TV, you might be wondering why everything you watch feels eerily sped up and smooth, like you’re watching a live broadcast all the time. You’re not imaginin…

linux guard什么进程,使用linux系统性能监控工具KSysguard监控远端主机介绍

KDE System Guard默认的窗口前端图形界面使用传感器(sensors)获得要显示的信息。传感器返回的可以是一个简单的数值或更复杂的信息如表格。针对不同的信息类型都提供了一个或多个显示界面。这些显示界面被组织在多个工作表中&#xff0c;工作表可以独立存储和加载。KSysguard主…

macbook充电_如何判断MacBook是否正在充电

macbook充电2p2play / Shutterstock2p2play / ShutterstockForgetting to charge your MacBook properly overnight can leave you with a headache in the morning. And if you’re troubleshooting a broken MacBook, checking if it’s able to charge is one way to rule o…

mysql记录

当没有用EXISTS引入子查询时&#xff0c;在选择列表中只能指定一个表达式转载于:https://www.cnblogs.com/niuben/p/9920741.html

PIL.Image convert to numpy array

当使用PIL.Image读取图像时&#xff0c;如果直接使用numpy.array()转换会出现错误&#xff1a; lst list() for file_name in os.listdir(dir_image):image PIL.Image.open(file_name)lst.append(image) arr numpy.array(lst) 此时&#xff0c;上述最后一行在执行时会出现错…

NFC服务器在Linux,linux 安装 libnfc ,打开串口PN532

硬件准备&#xff1a;USB转串口4针杜邦线PN532模块IC卡一张(比如门禁卡&#xff0c;饭卡等)软件准备&#xff1a;Ubuntu 物理机一台能够访问互联网1&#xff0c;将PN532与USB转串口连接好,放一张IC卡靠近PN532模块2&#xff0c;安装libnfc&#xff1a;chunliubuntu:~$ sudo apt…

chrome同步_如何在Chrome中打开或关闭同步

chrome同步Google Chrome lets you sync up your Google account to your browser across any device. When enabled, bookmarks, history, passwords, extensions, and themes—among many other settings—sync from your Google account, creating a seamless experience no…