您的位置:首页 > 理论基础 > 数据结构算法

【数据结构】二叉树的前中后序遍历递归和非递归实现

2016-01-28 22:24 597 查看
二叉树有很多操作,而二叉树的遍历只是其中的一个基本操作。

二叉树的遍历方式有3种:前序遍历,中序遍历,后序遍历。前中后遍历顺序是根据什么时候访问根节点来说的。

1.前序遍历

前序遍历也叫先序遍历。思路是先访问根节点,然后遍历左子树,最后遍历右子树。直到所有的节点都遍历完。

2.中序遍历

中序遍历的遍历步骤是先遍历左子树,然后访问根节点,最后遍历右子树。直到所有的节点都遍历完。

3.后序遍历

后序遍历的遍历顺序是先遍历左子树,然后遍历右子树,最后访问根节点。直到所有的节点都遍历完。

如果你仔细观察以上的文字,你会觉得所描述的遍历是非常抽象的,根节点,哪里的根节点?左子树,哪个根节点的左子树?右子树,哪个根节点的右子树?如果你再熟悉递归,你会立马想到递归,因为递归可以把抽象的问题一步一步来解决。用递归来遍历二叉树很简单,代码一目了然。

假如有这样一棵二叉树:



对于这样一棵树,前序遍历顺序是:RACDB

中序遍历的顺序是:CADRB

后序遍历的顺序是:CDABR

二叉树的遍历用递归来描述是简洁了,但是有时候考虑到效率。我们会用栈来模拟递归的过程。由于递归过程有栈帧,所以保存好栈帧是非递归遍历二叉树的难点。

下面是遍历二叉树的代码实现:

package 二叉树的遍历;

import java.util.*;
import java.io.*;
class BitNode
{
//声明一颗树的节点
char data;
BitNode LChild;
BitNode RChild;
}

public class Main
{
static BitNode[] bits=new BitNode[4];
/*
*树的结构
*     R
*    / \
*   A   B
*  / \
* C   D
*
*/
public static void createTree(BitNode root)
{

for (int i=0;i < 4;i++)
{
bits[i] = new BitNode();
bits[i].data = (char)('A' + i);

}
root.data = 'R';
root.LChild = bits[0];
root.RChild = bits[1];
bits[0].LChild = bits[2];
bits[0].RChild = bits[3];
}
/*
* 后续遍历:
*从根节点出发,只要当前节点存在,或者栈不为空,重复下面的操作:
*(1)从当前节点开始,进栈并走左子树,直到左子树为空
*(2)如果栈顶节点的右子树为空,或者栈顶结点的右孩子为刚才访问过的节点,
*    则退栈并访问,然后将当前节点指针置为空。
*(3)否则走右子树。
*/
public static  void post2(BitNode root)
{
Stack<BitNode> stack=new Stack<BitNode>();
BitNode p,q=null;
p=root;
while(p!=null||!stack.empty())
{
while(p!=null)
{
stack.push(p);
p=p.LChild;
}
if(!stack.empty())
{
p=stack.peek();
if(p.RChild==q||p.RChild==null)
/*无右孩子,或着右孩子以遍历过*/
{
visit(stack.pop());//访问根节点
q=p;//保存到q,为下一次已处理节点做前驱
p=null;
}
else{
p=p.RChild;
}
}
}
}

public static  void post1(BitNode root)
{
if (root == null)
return;
post1(root.LChild);
post1(root.RChild);
visit(root);
}
/*
* 中序遍历:
*从根节点出发,只要当前节点存在,或者栈不为空,重复下面的操作:
*(1)如果当前节点存在,则进栈并走左子树。
*(2)否则退栈并访问,然后走右子树
*/
public static  void inorder2(BitNode root)
{
Stack<BitNode> stack=new Stack<BitNode>();
BitNode p;
p=root;
while(p!=null||!stack.empty())
{
if(p!=null)
{
stack.push(p);
p=p.LChild;
}
else
{
p=stack.pop();
visit(p);
p=p.RChild;
}

}
}

public static  void inorder1(BitNode root)
{
if (root == null)
return;
inorder1(root.LChild);
visit(root);

inorder1(root.RChild);
}

public static  void pre1(BitNode root)
{
if (root == null)
return;
visit(root);
pre1(root.LChild);
pre1(root.RChild);
}

public static  void pre2(BitNode root)
{
Stack<BitNode> stack=new Stack<BitNode>();
stack.push(root);
while (!stack.empty())
{
BitNode node=stack.pop();
visit(node);
if (node.RChild != null)
{
stack.push(node.RChild);
}
if (node.LChild != null)
{
stack.push(node.LChild);
}
}
}

public static void visit(BitNode bit)
{
System.out.print(bit.data);
}
public static void main(String[] args)
{
BitNode root=new BitNode();
createTree(root);
System.out.println("先序递归遍历");
pre1(root);
System.out.println("\n\n先序非递归遍历");
pre2(root);
System.out.println("\n\n中序递归遍历");
inorder1(root);
System.out.println("\n\n中序非递归遍历");
inorder2(root);
System.out.println("\n\n后序递归遍历");
post1(root);
System.out.println("\n\n后序非递归遍历");
post2(root);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息