二叉树前序、中序、后序递归与非递归遍历+层序遍历(java)

前序递归遍历算法:访问根结点-->递归遍历根结点的左子树-->递归遍历根结点的右子树

 中序递归遍历算法:递归遍历根结点的左子树-->访问根结点-->递归遍历根结点的右子树

 后序递归遍历算法:递归遍历根结点的左子树-->递归遍历根结点的右子树-->访问根结点

层序遍历算法:将每个节点放入队列中。依据队列先进先出的特点,顺序遍历树。直到队列为空

二叉树为:

Java代码:

二叉树节点定义Treel.java:

package Test_1;

public class TreeNode {
	int data;
	TreeNode left;
	TreeNode right;
	
	public TreeNode(){};
	
	TreeNode(int data,TreeNode left, TreeNode right){
		super();//千万别忘了,不然会出错,如果没有这句在node9实例化时报错
		this.data = data;
		this.left = left;
		this.right = right;
	}
	
	public int getData(){
		return data;
	}
	
	public void setData(int data){
		this.data = data;
	}
	
	public TreeNode getLeft(){
		return left;
	}
	
	public void setLeft(TreeNode left){
		this.left = left;
	}
	
	public TreeNode getRight(){
		return right;
	}
	
	public void setRight(TreeNode right){
		this.right = right;
	}
}

二叉树遍历实现代码BinaryTree.java:

package Test_1;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

public class BinaryTree {
	//前序递归实现
	public void preOrderRe(TreeNode root){
		//System.out.println(biTree.value);
		if(root != null){
			System.out.print(root.getData()+", ");
			preOrderRe(root.getLeft());
			preOrderRe(root.getRight());
		}
	}
	
	//前序非递归的方式
	public void preOrderNonRecursive(TreeNode root){
		Stack<TreeNode> stack = new Stack<>();
		while(true){
			while(root !=null){
				System.out.print(root.getData()+", ");
				stack.push(root);
				root = root.getLeft();
			}
			if(stack.isEmpty()) break;//遍历完最后一个节点时调用这一句跳出循环
			root = stack.pop();
			root = root.getRight();
		}
	}
	
	//中序遍历+递归
	public void inOrder(TreeNode root){
		if(root != null){
			inOrder(root.getLeft());
			System.out.print(root.getData()+", ");
			inOrder(root.getRight());
		}
	}
	
	//中序遍历+非递归
	public void inOrderNonRecursive(TreeNode root){
		Stack<TreeNode> stack = new Stack<>();
		while(true){
			while(root != null){
				stack.push(root);
				root = root.getLeft();
			}
			if(stack.isEmpty()) break;
			root = stack.pop();
			System.out.print(root.getData()+", ");
			root = root.getRight();
		}
	}
	
	//后序遍历+递归
	public void postOrder(TreeNode root){
		if(root != null){
			postOrder(root.getLeft());
			postOrder(root.getRight());
			System.out.print(root.getData()+", ");
		}
	}
	
	//后续遍历+非递归(这是最难的一个)
    //主要思想:首先遍历root根节点的所有左节点,并依次入栈。对出栈的元素,如果没有右儿子或者
    //虽然有右儿子但右儿子已完成遍历,即可完成出栈;否则,再次入栈,并把右儿子入栈,遍历右
    //儿子的所有左儿子。
    //后序遍历的难点在于:需要判断上次访问的节点是位于左子树,还是右子树。若是位于左子树,
    //则需跳过根节点,先进入右子树,再回头访问根节点;若是位于右子树,则直接访问根节点。
	public void postOrderNonRecursive(TreeNode root){
		Stack<TreeNode> stack = new Stack<>();
		while(true){
			if(root !=null){
				stack.push(root);
				root = root.getLeft();
			}else{
				if(stack.isEmpty()) return;
				
				if(stack.lastElement().getRight() == null){//Vector中lastElement(),Returns the last component of the vector.
					root = stack.pop();
					System.out.print(root.getData()+", ");
					while(root == stack.lastElement().getRight()){
						System.out.print(stack.lastElement().getData()+", ");
						root = stack.pop();
						if(stack.isEmpty()){
							break;
						}
					}
				}
				
				if(!stack.isEmpty())
					root = stack.lastElement().getRight();
				else
					root = null;
			}
		}
	}
	
	//层序遍历
	/*offer,add区别:
	 *  一些队列有大小限制,因此如果想在一个满的队列中加入一个新项,多出的项就会被拒绝。 这时新的offer 方法
	 * 就可以起作用了。它不是对调用 add() 方法抛出一个 unchecked 异常,而只是得到由 offer() 返回的 false。 
	 *  poll,remove区别: 
	 *  remove() 和 poll() 方法都是从队列中删除第一个元素。remove() 的行为与 Collection 接口的版本相似, 
	 *  但是新的 poll() 方法在用空集合调用时不是抛出异常,只是返回 null。因此新的方法更适合容易出现异常条件的情况。
	 */
	public void levelOrder(TreeNode root){
		TreeNode temp;
		Queue<TreeNode> queue = new LinkedList<TreeNode>();
		queue.offer(root);
		while(!queue.isEmpty()){
			temp = queue.poll();
			System.out.print(temp.getData()+", ");
			if(temp.getLeft() != null)
				queue.offer(temp.getLeft());
			if(temp.getRight() != null)
				queue.offer(temp.getRight());
		}
	}
	
	public static void main(String[] args) {
		//注意如果创建使用函数二叉树,则必须逆序建立,先建立子节点,再逆序往上建立,因为非叶子结点会使用到下面的节点,
		//而初始化是按顺序初始化的,不逆序建立会报错;如果不适用函数创建二叉树,像下面这样做,不必用逆序建立
		TreeNode node9 = new TreeNode(8,null, null);
		TreeNode node8 = new TreeNode(4,null, null);
		TreeNode node7 = new TreeNode(2, null, null);
		TreeNode node6 = new TreeNode(7,null, node9);
		TreeNode node5 = new TreeNode(5,node8, null);
		TreeNode node4 = new TreeNode(1, null, node7);
		TreeNode node3 = new TreeNode(9, node6, null);
		TreeNode node2 = new TreeNode(3, node4, node5);
		TreeNode node1 = new TreeNode(6, node2,node3);
		
		BinaryTree tree = new BinaryTree();
		System.out.println("先序遍历二叉树(递归):");
		tree.preOrderRe(node1);
		System.out.println();
		
		System.out.println("先序遍历二叉树(非递归):");
		tree.preOrderNonRecursive(node1);
		System.out.println();
		
		System.out.println("中序遍历二叉树(递归):");
		tree.inOrder(node1);
		System.out.println();
		
		System.out.println("中序遍历二叉树(非递归):");
		tree.inOrderNonRecursive(node1);
		System.out.println();
		
		System.out.println("后序遍历二叉树(递归):");
		tree.postOrder(node1);
		System.out.println();
		
		System.out.println("后序遍历二叉树(非递归):");
		tree.postOrderNonRecursive(node1);
		System.out.println();
		
		System.out.println("层序遍历二叉树(递归):");
		tree.levelOrder(node1);
		System.out.println();
	}
}

运行结果:

猜你喜欢

转载自blog.csdn.net/Quantum_Dog/article/details/85998071