二叉树的先序、中序、后序遍历

  二叉树的遍历方法有多种,首先我想先改变这几个遍历的名字(前根序遍历,中根序遍历,后根序遍历);前中后本来就是相对于根结点来说的,少一个字会产生很多不必要的误解。

  先简单描述一下这三种遍历方法的区别:

  1. 先序遍历:先遍历根结点,然后遍历左子树,最后遍历右子树。上图中的先序遍历结果是ABDHECFG
  2. 中序遍历:先遍历左子树,然后遍历根结点,最后遍历右子树。上图中的中序遍历结果是HDBEAFCG
  3. 后序遍历:先遍历左子树,然后遍历右子树,最后遍历根节点。上图中的后序遍历结果是HDEBFGCA

先序遍历:

  递归方式:

 1 //前序遍历
 2     public void PreOrder(BinaryTreeNode<E> root){
 3         if(root == null)
 4             return  ;
 5         else{
 6             System.out.print(root+" ");
 7             PreOrder(root.lchild) ;
 8             PreOrder(root.rchild) ;
 9         }
11     }

非递归方式:借用栈的结构特点来实现,具体步骤如下:

  1. 首先申请一个栈,记为stack
  2. 然后将头结点压入stack中
  3. 每次从stack中弹出栈顶元素,记为cur,然后打印cur节点的值。如果cur右孩子不为空的话,将cur的右孩子先压入stack中,最后如果cur的做孩子不为空的话将cur的做孩子压入栈stack中
  4. 不断重复步骤3,直到stack为空,全部过程结束。

中序遍历:

  递归方式:

 1 //中序遍历
 2     public void MidOrder(BinaryTreeNode<E> root){
 3         if(root == null)
 4             return  ;
 5         else{
 6             MidOrder(root.lchild) ;
 7             System.out.print(root+" ");
 8             MidOrder(root.rchild) ;
 9         }
10     }

  非递归方式:也是借用栈的结构特点来实现,具体步骤如下:

  1. 申请一个新的栈,记为stack,申请一个变量cur,初始时令cur等于头结点
  2. 先把cur节点压入栈中,对以cur节点为头的整棵子树来说,依次把整棵树的左子树压入栈stack中,及不断令cur = cur.left,然后重复步骤2
  3. 不断重复步骤2,知道发现cur为空,此时从stack中弹出一个节点,记为node,打印node的值,并让cur = node.right,然后继续重复步骤2。

后序遍历:

  递归方式:

 1 //后序遍历
 2     public void LastOrder(BinaryTreeNode<E> root){
 3         if(root == null)
 4             return  ;
 5         else{
 6             LastOrder(root.lchild) ;
 7             LastOrder(root.rchild) ;
 8             System.out.print(root+" ");
 9         }
10     }

  非递归方式:也是借用栈的结构特点来实现,具体步骤如下:

  1. 申请一个栈,记为stack,将头结点压入stack,同时设置两个变量h和cur,在整个流程中,h代表最近一次弹出并打印的节点,cur代表当前stack的栈顶节点,初始时令h为头结点,cur为null;
  2. 每次令cur等于当前stack的栈顶元素,但是补充stack中弹出节点,此时分为以下三种情况判断是否弹出元素:
    1. 如果cur的做孩子不为null,并且h不等于cur的左孩子,也不等于cur的右孩子,则把cur的左孩子压入栈stack中
    2. 如果情况1不成立,并且cur的右孩子不为null,并且h不等于cur的右孩子,则把cur的右孩子压入栈stack中
    3. 如果情况1和2都不成立,则从stack中弹出cur元素并打印,然后令h等于cur
  3. 一直重复步骤2,直到stack为空并且cur为空,过程停止

根据遍历结果构造二叉树

根据遍历结果我们可以构造出原始的二叉树,在此过程中我们只能通过二叉树的先序+中序中序+后序来构造:

已知一棵二叉树的先序序列和中序序列,构造该二叉树的过程如下:

  1. 根据前根序序列的第一个元素建立根结点;
  2. 在中根序序列中找到该元素,确定根结点的左右子树的中根序序列;
  3. 在前根序序列中确定左右子树的前根序序列;
  4. 由左子树的前根序序列和中根序序列建立左子树;
  5. 由右子树的前根序序列和中根序序列建立右子树。

已知一棵二叉树的后序序列和中序序列,构造该二叉树的过程如下:

  1. 根据后根序序列的最后一个元素建立根结点;
  2. 在中根序序列中找到该元素,确定根结点的左右子树的中根序序列;
  3. 在后根序序列中确定左右子树的后根序序列;
  4. 由左子树的后根序序列和中根序序列建立左子树;
  5. 由右子树的后根序序列和中根序序列建立右子树。
时间: 2024-12-28 11:44:04

二叉树的先序、中序、后序遍历的相关文章

Java数据结构四之——二叉树的前、中、后序遍历

程序来自Program Creek 前 Preorder binary tree traversal is a classic interview problem about trees. The key to solve this problem is to understand the following: What is preorder? (parent node is processed before its children) Use Stack from Java Core lib

算法进化历程之“根据二叉树的先序和中序序列输出后序序列”

巧若拙(欢迎转载,但请注明出处:http://blog.csdn.net/qiaoruozhuo) 前不久在看到一个作业"根据二叉树的先序和中序序列输出后序序列",当时我参考<数据结构与算法(C语言)习题集>上的做法,先根据先中序序列确定一颗二叉树,然后后序遍历二叉树输出后序序列. 函数采用了递归算法,利用函数传入的先序和中序序列的左右边界,确定要处理的序列段,生成相应的二叉树. 基本思路是,把该段先序序列的第一个元素作为当前二叉树的根结点,然后在中序序列找到根结点.根结点

通过二叉树的中序序列和后序序列获取前序序列

二叉树的遍历方式常见的三种是:先序遍历(ABC).中序遍历(BAC).后序遍历(BCA) 先序遍历: 若二叉树为空,则空操作:否则: 访问根结点; 先序遍历左子树: 先序遍历右子树. 中序遍历: 若二叉树为空,则空操作:否则: 中序遍历左子树: 访问根结点: 中序遍历右子树. 后序遍历: 若二叉树为空,则空操作:否则: 后序遍历左子树: 后序遍历右子树: 访问根结点. 在学习到 根据遍历序列确定二叉树 时,知道了:可以通过二叉树的先中或者中后遍历序列唯一确定一棵二叉树. 根据算法描述 使用jav

先序序列和后序序列并不能唯一确定二叉树

数据结构的基础知识中重要的一点就是能否根据两种不同遍历序列的组合(有三种:先序+中序,先序+后序,中序+后序),唯一的确定一棵二叉树.然后就是根据二叉树的不同遍历序列(先序.中序.后序),重构二叉树.显然,这三种组合并不是都能唯一确定二叉树的,其中先序+后序就不能唯一确定一棵二叉树,其他两种组合可以唯一的确定一颗二叉树. 由先序序列和后序序列不能唯一确定一棵二叉树,因无法确定左右子树两部分. 反例:任何结点只有左子树的二叉树和任何结点只有右子树的二叉树,其前序序列相同,后序序列相同,但却是两棵不

中序表达式转后序表式式

中序表达式转后序表式式: 将中序表达式所有括号补全,然后将所有运算符向右移出无匹配的第一个右括号,去掉括号即为后序表式式 举例: 原式:a+b*(c+d/e) 补全括号:(a+(b*(c+(d/e)))) 操作符右移:(a(b(c(de)/)+)*)+ 去掉括号:abcde/+*+ 中序表达式转前序表式式: 将中序表达式所有括号补全,然后将所有运算符向左移出无匹配的第一个左括号,去掉括号即为前序表式式 举例: 原式:a+b*(c+d/e) 补全括号:(a+(b*(c+(d/e)))) 操作符右移

hdu1710-Binary Tree Traversals (由二叉树的先序序列和中序序列求后序序列)

http://acm.hdu.edu.cn/showproblem.php?pid=1710 Binary Tree Traversals Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4210    Accepted Submission(s): 1908 Problem Description A binary tree is a

华南理工数据结构大作业第二题 二叉树各种操作深度结点个数后序前序中序层次求祖先

/*#include<iostream> #include<windows.h> using namespace std ; struct BTNode { char data ; BTNode *left ; BTNode *right ; BTNode () { left = NULL ; right = NULL ; } } ; int main () { cout <<"题目所给的二叉树用括号表示法后表示为:A(B(D,E(H(J,K(L,M(,N))

二叉树遍历算法——包含递归前、中、后序和层次,非递归前、中、后序和层次遍历共八种

首先,要感谢网上的参考资料. http://mengliao.blog.51cto.com/876134/1178079(作者:BlackAlpha) http://blog.csdn.net/fzh1900/article/details/14056735(作者:_云淡风轻) http://blog.csdn.net/stpeace/article/details/8138458(作者:stpeace) 二叉树是使用的比较广泛的一种数据结构,这里我写了二叉树的相关操作,包括初始化.新建.以及遍

日常学习随笔-用链表的形式实现普通二叉树的新增、查找、遍历(前、中、后序)等基础功能(侧重源码+说明)

一.二叉树 1.二叉树的概念 二叉树是每个节点最多有两个子树的树结构.通常子树被称作"左子树"(left subtree)和"右子树"(right subtree),其次序不能任意颠倒. 2.性质 (1)若二叉树的层次从0开始,则在二叉树的第i层至多有2^i个结点(i>=0): (2)高度为k的二叉树最多有2^(k+1) - 1个结点(k>=-1). (空树的高度为-1): (3)对任何一棵二叉树,如果其叶子结点(度为0)数为m, 度为2的结点数为n,

分别求二叉树前、中、后序的第k个节点

一.求二叉树的前序遍历中的第k个节点 //求先序遍历中的第k个节点的值 int n=1; elemType preNode(BTNode *root,int k){ if(root==NULL) return ' '; if(n==k) return root->data; n++; elemType ch = preNode(root->lchild,k); if(ch!=' ') return ch; ch = preNode(root->rchild,k); return ch;