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

#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…

火狐标签在中间_在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中打开了大量内容繁重的网页&…

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…

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…

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…

linux系统输入指令,详解linux系统输入输出管理和vim的常用功能

####系统中输入输出的管理####1.理解系统的输入输出重定向输入重定向是指把文件导入到命令中&#xff0c;而输出重定向则是把原本要输出到屏幕的数据信息写入到指定文件中。2.管理输入输出的符号##输出重定向> ##重定向正确输2> ##重定向错误输出&> …

Deep Learning(深度学习)学习笔记整理(二)

本文整理了网上几位大牛的博客&#xff0c;详细地讲解了CNN的基础结构与核心思想&#xff0c;欢迎交流 [1]Deep learning简介 [2]Deep Learning训练过程 [3]Deep Learning模型之&#xff1a;CNN卷积神经网络推导和实现 [4]Deep Learning模型之&#xff1a;CNN的反向求导及练习 …

百度新闻 谷歌新闻_每日新闻摘要:到目前为止,Google I / O提供的最佳信息

百度新闻 谷歌新闻Google’s yearly developer conference started yesterday, and the keynote was chock-full of announcements, demos, and some utterly mind-blowing tech. From Assistant to Android, here’s some of the best stuff to come out of I/O 2019 so far. …

word2016 语法检查_如何改进Microsoft Word的语法检查器

word2016 语法检查Microsoft Word comes with a powerful grammar checker, but many of its advanced grammar detection features are disabled by default. Grammarly is popular, but you don’t need it to add grammar checking to Word. Word itself contains a free al…

linux服务器硬件监控,Linux服务器实时监控加载硬件信息

Linux服务器监控之实时监控加载硬件信息Linux负有盛名的特点之一是其非凡的稳定性。然而&#xff0c;如果您的硬件有缺陷或配置不正确&#xff0c;即使是世界上最稳定的操作系统也不会对您有什么帮助。计算机系统是由软件系统硬件系统组成的&#xff0c;检测硬件状态对于保障整…

Using Python with Oracle

2019独角兽企业重金招聘Python工程师标准>>> Using Python with Oracle This page discusses using Python with Oracle. The page is based on the cx_oracle Python extension module. It was developed on a VM running Oracle Enterprise Linux 6U4 runnng Orac…

小米oj 反向位整数(简单位运算)

反向位整数 序号&#xff1a;#30难度&#xff1a;一般时间限制&#xff1a;1000ms内存限制&#xff1a;10M 描述 输入32位无符号整数&#xff0c;输出它的反向位。 例&#xff0c;输入4626149&#xff08;以二进制表示为00000000010001101001011011100101&#xff09;&#xff…

如何在Microsoft Word中插入签名

Adding your signature to a Microsoft Word document is the ultimate way to personalize it as your own, especially for documents like letters or contracts. If you want to add a signature to a Word document, here’s how. 将签名添加到Microsoft Word文档是将其个…

jdk 1结尾和2结尾_“与巢一起工作”的结尾对您意味着什么

jdk 1结尾和2结尾korisbo/Shutterstock科里斯博/ ShutterstockGoogle announced the end of “Works With Nest” at Google I/O 2019. Many companies, from IFTTT to Philips Hue, use Works With Nest to automate your smarthome. Those automations will break soon. Goog…

linux 桌面显示视频播放器,Ubuntu 13.10开启媒体播放器VLC桌面通知的步骤

VLC是一款多功能的媒体播放器&#xff0c;支持众多音频及视频格式&#xff0c;能够适用于Ubuntu等系统&#xff0c;而VLC播放器有桌面通知功能&#xff0c;需要手动开启&#xff0c;下面小编就以Ubuntu 13.10为例&#xff0c;给大家详细介绍下Ubuntu 13.10开启VLC桌面通知的步骤…