#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

//
知树的前序遍历,后序遍历,怎么求中序遍历?
通过对同一棵二叉树三种遍历方式的分析,概括出由前序、中序或由中序、后序遍历结果快速还原二叉树的方法。 
二叉树是最为常用的数据结构,它的实际应用非常广泛。二叉树的遍历方式有三种,前序遍历、中序遍历、后序遍历。先序遍历的顺序为: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

后序为 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);

}

}

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

二叉树的前序、中序、后序遍历与创建相关推荐

  1. java中二叉树_Java工程师面试1000题224-递归非递归实现二叉树前、中、后序遍历...

    224.使用递归和非递归实现二叉树的前.中.后序遍历 使用递归来实现二叉树的前.中.后序遍历比较简单,直接给出代码,我们重点讨论非递归的实现. class Node { public int valu ...

  2. C++实现二叉树 前、中、后序遍历(递归与非递归)非递归实现过程最简洁版本

    本文并非我所写,是复制的该链接中的内容: 最近学习二叉树,想编程实现递归和非递归的实现方式: 递归的方式就不说了,因为大家的递归程序都一样:但是对于非递归的实现方式, 根据这几天的查阅资料已看到差不多 ...

  3. 【LeetCode | 二叉树前、中、后序遍历{迭代法}实现】

    1.前序遍历 // 解题思路:利用栈的原理实现以迭代方法来前序遍历(根左右)二叉树 class Solution { public:vector<int> preorderTraversa ...

  4. java数据结构学习笔记-二叉树前、中、后序遍历

    public class BinaryTreeDemo {public static void main(String args[]){Employee emp1= new Employee(1,&q ...

  5. 【LeetCode | 二叉树前、中、后序遍历{递归法}实现】

    1.前序遍历 #include <iostream> #include <vector> #include <queue> #include <algorit ...

  6. 二叉树前、中、后序线索化及遍历

    public class ThreadedBinaryTree {public static void main(String[] args){Heronodes node1=new Heronode ...

  7. 二叉树的前序中序后序遍历

    二叉树的前序中序后序遍历 二叉树的遍历 前序遍历 中序遍历 后序遍历 总结 二叉树的遍历 二叉树的遍历有前序遍历,中序遍历,后序遍历三种. 今天我把二叉树的遍历方法给大家总结一下,也算对我自己学习的一 ...

  8. 【二叉树Java】二叉树遍历前序中序后序遍历的非递归写法

    本文主要介绍二叉树前序中序后序遍历的非递归写法 在探讨如何写出二叉树的前序中序后序遍历代码之前,我们先来明确一个问题,前序中序后序遍历根据什么区分? 二叉树的前序中序后序遍历,是相较根节点说的.最先遍 ...

  9. 二叉树的前序中序后序遍历java代码实现

    1.前序遍历概述 前序遍历(VLR) 是二叉树遍历的一种,也叫做先根遍历.先序遍历.前序周游,可记做根左右.前序遍历首先访问根结点然后遍历左子树,最后遍历右子树. 若二叉树为空则结束返回,否则: (1 ...

  10. 二叉树遍历(递归实现前序/中序/后序遍历)

    1. 准备工作 我们先定义一棵普通的二叉树,如下图 2. 前序遍历 通过递归进行遍历: 如果二叉树为空,则操作返回: 如果非空,否则从根结点开始,然后遍历左子树,再遍历右子树. 前序遍历的结果是:AB ...

最新文章

  1. LeetCode简单题之交替合并字符串
  2. uniapp里的mounted_uni-app 生命周期函数执行顺序
  3. Mac用Java写出hello,mac中c#的helloworld
  4. 微信程序开发系列教程(一)开发环境搭建
  5. 光纤测试时怎么选择对应项目的测试标准及测试仪?
  6. 【POJ - 1836】Alignment(dp,LIS,最长上升子序列类问题)
  7. 关于Nginx的一些优化(突破十万并发)。
  8. 计算机ps屏幕背景颜色怎么换,win7系统ps背景颜色怎么换?七步教您轻松处理
  9. 百度图标html代码,css 画的百度LOGO
  10. 过孔在覆铜后不出现十字孔
  11. 训练营四教官打死网瘾少年案今开庭审理
  12. PCB做SET连片,转批量时发现利用率非常低,有遇到过吗?
  13. 华为鸿蒙是安卓9,鸿蒙“翻车”了?网友发现全新的鸿蒙系统居然是安卓9.0,华为骗我们?...
  14. 计算机开机显示器不亮,电脑开机显示器不亮该如何解决
  15. 第十五篇:UE4 漫游Matinee的制作和如何在漫游中实现自由转向(改进)
  16. Chrome浏览器导出Excel,失败-网络错误
  17. docker私服配置
  18. linux 那些事儿系列
  19. 如何下载沧州市卫星地图高清版大图
  20. Boilsoft Video Splitter绿色便携版下载(免序列号)

热门文章

  1. cad.net 获取所有已经安装的cad版本信息
  2. Celery 之异步任务、定时任务、周期任务
  3. 分析uboot中 make xxx_config过程
  4. [LeetCode] Palindrome Linked List
  5. 80x86 CPU 的工作模式
  6. POJ 1745 Divisibility DP
  7. Mingw下g++编译执行顺序错误
  8. linux中用户忘记root的密码--ubuntu版本
  9. Linux文件读写改权限详解
  10. Linux环境变量PSI指什么,PSI 文件扩展名: 它是什么以及如何打开它?