二叉树的遍历(Java实现)

本文详细介绍了二叉树的多种遍历方法,包括递归和非递归的前序、中序、后序遍历及层序遍历,并提供了具体的Java实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

主要是二叉树的遍历,包括递归遍历和非递归遍历

package util;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;

public class BinaryNode<T> {
	/**
	 * 泛型BinaryNode类
	 */
	public T item;
	
	public BinaryNode<T> left,right;//左右子树
	
	public BinaryNode(T item)
	{
		this.item = item;
		left = right = null;
	}	
	public BinaryNode (T item, BinaryNode<T> left, BinaryNode<T> right)
	{
		this.item = item;
		this.left = left;
		this.right = right;
	}

	public T getNodeValue() {
		return item;
	}
	public void setNodeValue(T item) {
		this.item = item;
	}
	public BinaryNode<T> getLeft() {
		return left;
	}
	public void setLeft(BinaryNode<T> left) {
		this.left = left;
	}
	public BinaryNode<T> getRight() {
		return right;
	}
	public void setRight(BinaryNode<T> right) {
		this.right = right;
	}
	
	//判断是否为叶子
	public boolean isLeaf(){
		return (left==null)&&(right==null);
	}
	
	//前序遍历二叉树(递归)
	public List<BinaryNode<T>> toStringPreorder(BinaryNode<T> node){
		List<BinaryNode<T>> list=new ArrayList<BinaryNode<T>>();
		list.add(node);
		if (node.left!=null) {
			list.addAll(toStringPreorder(node.left));
		}
		if (node.right!=null) {
			list.addAll(toStringPreorder(node.right));
		}
		return list;
	}
	//前序遍历二叉树(非递归)
	public List<BinaryNode<T>> toStringPreorderNoRec(BinaryNode<T> node){
		List<BinaryNode<T>> list=new ArrayList<BinaryNode<T>>();
		ArrayDeque<BinaryNode<T>> stack=new ArrayDeque<BinaryNode<T>>();
		while ((node!=null)||!stack.isEmpty()) {
			if (node!=null) {
				list.add(node);
				stack.push(node);
				node=node.left;
			} else {
				node=stack.peek();			
				stack.pop();
				node=node.right;
			}
		}		
		return list;
	}
	
	//中序遍历二叉树
	public List<BinaryNode<T>> toStringInorder(BinaryNode<T> node){
		List<BinaryNode<T>> list=new ArrayList<BinaryNode<T>>();
		if (node.left!=null) {
			list.addAll(toStringPreorder(node.left));
		}
		list.add(node);
		if (node.right!=null) {
			list.addAll(toStringPreorder(node.right));
		}
		return list;
	}
	//中序遍历二叉树(非递归)
	public List<BinaryNode<T>> toStringInorderNoRec(BinaryNode<T> node){
		List<BinaryNode<T>> list=new ArrayList<BinaryNode<T>>();
		ArrayDeque<BinaryNode<T>> stack=new ArrayDeque<BinaryNode<T>>();
		while ((node!=null)||!stack.isEmpty()) {
			if (node!=null) {				
				stack.push(node);
				node=node.left;
			} else {
				node=stack.peek();
				list.add(node);
				stack.pop();
				node=node.right;
			}
		}		
		return list;
	}
	
	//后序遍历二叉树
	public String toStringPostorder(){
		String result="";
		if (left!=null) {
			result += left.toStringPostorder();
		}		
		if (right!=null) {
			result += right.toStringPostorder();
		}
		result += item;
		return result;
	}
	//后序遍历二叉树(非递归)
	/**
	 * 先遍历树的逆后序遍历(根、右、左),在翻转逆后序遍历就是后序遍历二叉树(左、右、根)
	 * @return result栈
	 */
	public ArrayDeque<BinaryNode<T>> toStringPostorderNoRec(BinaryNode<T> node){
		ArrayDeque<BinaryNode<T>> stack=new ArrayDeque<BinaryNode<T>>();
		ArrayDeque<BinaryNode<T>> result=new ArrayDeque<BinaryNode<T>>();
		while ((node!=null)||!stack.isEmpty()) {
			if (node!=null) {
				result.push(node);
				stack.push(node);
				node=node.right;
			} else {
				node=stack.peek();
				stack.pop();
				node=node.left;
			}
		}		
		return result;
	}
	//后序遍历二叉树2(非递归)
	/**
	 * 要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它;
	 * 或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。若非上述两种情况,
	 * 则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。
	 * @return result栈
	 */
	public ArrayList<BinaryNode<T>> toStringPostorderNoRec2(BinaryNode<T> root){
		ArrayDeque<BinaryNode<T>> stack=new ArrayDeque<BinaryNode<T>>();
		ArrayList<BinaryNode<T>> result=new ArrayList<BinaryNode<T>>();
		BinaryNode<T> curr;//当前栈顶指针
		BinaryNode<T> pre=null;//前一次访问节点
		stack.push(root);
		while (!stack.isEmpty()) {
			curr=stack.peek();
			if ((curr.left==null&&curr.right==null)||(pre!=null&&(pre==curr.left||pre==curr.right))) {
				result.add(curr);//输出结果
				stack.pop();
				pre=curr;
			} else {
				if (curr.right!=null) {
					stack.push(curr.right);
				} 
				if (curr.left!=null) {
					stack.push(curr.left);
				}
			}
		}		
		return result;
	}
	
	//层序遍历(广度优先遍历)
	public List<BinaryNode<T>> toStringLevelOrder(){
		List<BinaryNode<T>> list=new ArrayList<BinaryNode<T>>();
		Queue<BinaryNode<T>> queue=new ArrayDeque<BinaryNode<T>>();
		queue.offer(this);//root
		while (!(queue.isEmpty())) {
			list.add(queue.peek());
			BinaryNode<T> node=queue.poll();			
			if (node.left != null) {
				queue.offer(node.left);
			}
			if (node.right != null) {
				queue.offer(node.right);
			}
		}
		return list;
	}
	
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值