二叉树的遍历

二叉树的遍历应该说是非常常见的,用递归的话程序非常简单明了,而有的时候需要写非递归的遍历程序,这个时候就需要对此有一定的了解。

二叉树的遍历根据根节点和左右子节点遍历顺序的不同,可以分为三种:前序遍历,中序遍历,后序遍历。前序遍历就是先根节点->左节点->右节点。非递归前序遍历编写最简单,最难的是后续遍历。下面就来一一写出它们的程序,这里用的是Java。非递归遍历是一种DFS(深度优先搜素),从根节点开始一直遍历到叶子节点,然后在从根节点往另一个路径继续遍历。这里用到的数据结构是栈。Java里面用的是Stack类,它是数组实现,也可以用链表LinkedList来做栈。其实递归遍历也用到了栈,只不过是系统栈,没有显示的输出。

Node节点的定义:

public  class Node<T>
{
	private T element;
	private Node<T> left;
	private Node<T> right;
	public Node(T element,Node<T> left,Node<T> right)
	{
		this.element=element;
		this.left=left;
		this.right=right;
	}
}


递归二叉树遍历:

//前序遍历
public void printTree(Node<T> node)
{
	if(node!=null)
	{
		System.out.print(node.element+" ");
		printTree(node.left);
		printTree(node.right);

	}
}
//中序遍历
public void printTree(Node<T> node)
{
	if(node!=null)
	{
		printTree(node.left);
		System.out.print(node.element+" ");
		printTree(node.right);
	}
}
//后续遍历
public void printTree(Node<T> node)
{
	if(node!=null)
	{
		printTree(node.left);
		printTree(node.right);
		System.out.print(node.element+" "); 
	}
}


非递归二叉树遍历:

//前序遍历 非递归实现 三种遍历中最简单的
public void preTrave(Node<T> root)
{
	if(root==null)
		return;
	Stack<Node> st=new Stack<Node>();
	st.push(root);
	while(!st.isEmpty())
	{
		Node<T> n=st.pop();
		System.out.print(n.element+" ");
		if(n.right!=null)	
			st.push(n.right);  //先入栈右节点,再入栈左节点
		if(n.left!=null)	
			st.push(n.left);
	}	
}

//中序遍历 非递归实现 三种遍历中的
public void midTrave(Node<T> root)
{
	if(root==null)
		return;
	Stack<Node> st=new Stack<Node>();
	Node<T> no=root;
	while(no!=null || !st.isEmpty())
	{
		while(no!=null)
		{
			st.push(no); //不停地插入左节点
			no=no.left;
		}
		if(!st.isEmpty())
		{
			Node<T> n=st.pop();
			System.out.print(n.element+" ");
			no=n.right;  //获取出栈节点的右节点
		}
	}	
}

//后序遍历 非递归实现 三种遍历中是最难的,需要每个节点保存一个变量代表是否被读取过
public void postTrave(Node<T> root)
{
	if(root==null)
		return;
	Map.Entry<Node,Boolean> me;//这里用到Map内部类,类似于C++的pair函数,否则要自己重写个类
	Stack<Map.Entry<Node,Boolean>> st=new Stack<Map.Entry<Node,Boolean>>();
	Node<T> no=root;
	while(no!=null || !st.isEmpty())
	{
		while(no!=null)
		{
			me=new AbstractMap.SimpleEntry(no,false);
			st.push(me); //不停地插入左节点
			no=no.left;
		}
		if(!st.isEmpty())
		{
			
			Map.Entry<Node,Boolean> n=st.pop();
			if(n.getValue()==false)
			{
				st.push(n);
				n.setValue(true);   //代表读过该节点一次
				no=n.getKey().right;
			}
			else   //代表出栈的节点右节点已经读取
			{
				System.out.print(n.getKey().element+" ");
				no=null;  
			}
		}
	}	
}


除了上面的三种遍历,二叉树还可以分层遍历。这就是BFS(广度优先搜索),先第一层,再第二层,以此类推。BFS用到的数据结构是队列,先入先出。程序如下,它和前序遍历类似,只不过把栈改成了队列,然后左右节点进入的顺序掉了一下。

程序如下:

//按层遍历 就是将前序遍历的栈改用为队列,左右节点入队顺序改变一下
public void cengTrave(Node<T> root)
{
	if(root==null)
		return;
	ArrayDeque<Node> st=new ArrayDeque<Node>();
	st.offer(root);
	while(!st.isEmpty())
	{
		Node<T> n=st.pop();
		System.out.print(n.element+" ");
		if(n.left!=null)	
			st.offer(n.left);  //先左节点入队列,再右节点
		if(n.right!=null)	
			st.offer(n.right);
	}	
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值