二叉树的前序、中序、后序、层次遍历(递归+非递归)+层次遍历分层输出-java实现

总结一下,二叉树的各种遍历的递归和非递归实现,以及层次遍历(每一层输出一行)

实现代码如下:
package stone.offer.scu;

import java.awt.HeadlessException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

//二叉树的遍历

public class TraversalBiTree {
	public static void main(String[] args) {
		//以数组形式生成一颗完全二叉树
		TreeNode[] treeNodes = new TreeNode[10];
		for (int i = 0; i < 10; i++) {
			treeNodes[i] = new TreeNode(i);
		}
		for (int i = 0; i < 10; i++) {
			if (i*2+1 < 10) {
				treeNodes[i].left = treeNodes[i*2+1];
			}
			if (i*2+2 < 10) {
				treeNodes[i].right = treeNodes[i*2+2];
			}
		}
//		PreOrder(treeNodes[0]);
//		postOrderRe(treeNodes[0]);
//		postOrder(treeNodes[0]);
		LayerTravel(treeNodes[0]);
		
	}
	//前序遍历--递归
	public static void PreOrderRe(TreeNode treeNode) {
		if (treeNode == null) {
			return;
		}else {
			System.out.println(treeNode.val);
			PreOrderRe(treeNode.left);
			PreOrderRe(treeNode.right);
		}
		
	}
	//前序遍历--非递归借助栈
	public static void PreOrder(TreeNode treeNode) {
		Stack<TreeNode> stack = new Stack<>();
		System.out.println("前序非递归:");
		while (treeNode != null || !stack.isEmpty()) {
			while (treeNode != null) {
				System.out.print(treeNode.val + " ");
				stack.push(treeNode);
				treeNode = treeNode.left;
			}
			if (!stack.isEmpty()) {
				treeNode = stack.pop();
				treeNode = treeNode.right;
			}
		}
	}
	
	//中序遍历-递归
	public static void midOrderRe(TreeNode treeNode) {
		if (treeNode == null) {
			return;
		}else {
			midOrderRe(treeNode.left);
			System.out.println(treeNode.val);
			midOrderRe(treeNode.right);
		}
	}
	//中序遍历-非递归
	public static void midOrder(TreeNode treeNode) {
		Stack<TreeNode> stack = new Stack<>();
		while (treeNode != null || !stack.isEmpty()) {
			while (treeNode != null) {
				stack.push(treeNode);
				treeNode = treeNode.left;
			}
			if (!stack.isEmpty()) {
				treeNode = stack.pop();
				System.out.println(treeNode.val);
				treeNode = treeNode.right;
			}
		}
	}
	
	//后序遍历--递归
	public static void postOrderRe(TreeNode treeNode) {
		if (treeNode == null) {
			return;
		}else {
			postOrderRe(treeNode.left);
			postOrderRe(treeNode.right);
			System.out.print(treeNode.val + " ");
		}
	}
	//后序遍历-非递归
//	后序遍历递归定义:先左子树,后右子树,再根节点。
//	后序遍历的难点在于:需要判断上次访问的节点是位于左子树,还是右子树。

	
	public static /*ArrayList<Integer>*/ void postOrder(TreeNode treeNode) {
//		ArrayList<Integer> res = new ArrayList<>();
		if (treeNode == null) {
//			return res;
			return;
		}
		Stack<TreeNode> stack = new Stack<>();
		TreeNode cur = treeNode;  //用来记录当前访问结点
		TreeNode pre = null; // 记录上次访问结点
		
		//先把左枝全入栈
		while (cur != null) {
			stack.push(cur);
			cur = cur.left;
		}
		while (!stack.isEmpty()) {
			cur = stack.pop();
			//如果当前访问结点的右孩子为空 或 与上次访问结点相同(说明顺序为:右孩子->根)
			if (cur.right == null || cur.right == pre) {
//				res.add(cur.val);
				System.out.print(cur.val + " ");  //访问
				pre = cur; //更新上次访问结点
			}else {
				//如果为根结点,再次入栈
				stack.push(cur);
				cur = cur.right; //再将其右孩子入栈
				while (cur != null) {
					stack.push(cur); 
					cur = cur.left;  //继续放入右孩子的左枝
				}
			}
		}
//		return res;
		
	}
	
	//层次遍历   队列
	public static void LayerTravel(TreeNode treeNode) {
		if (treeNode == null) {
			return;
		}
		Queue<TreeNode> queue = new LinkedList<>();
		queue.add(treeNode);
		while (!queue.isEmpty()) {
			TreeNode cur = queue.poll();
			System.out.print(cur.val + " ");
			if (cur.left != null) {
				queue.add(cur.left);
			}
			if (cur.right != null) {
				queue.add(cur.right);
			}
		}
	}
	
	//层次遍历-- 队列 单行打印
	public static ArrayList<ArrayList<Integer>> layerTravel(TreeNode treeNode) {
		ArrayList<Integer> layer = new ArrayList<>();
		Queue<TreeNode> queue = new LinkedList<>();
		ArrayList<ArrayList<Integer>> res = new ArrayList<>();
		
		if (treeNode == null) {
			return res;
		}
		
		queue.add(treeNode);
		int start = 0,end = 1;
		while (!queue.isEmpty()) {
			TreeNode cur = queue.poll();
			layer.add(cur.val);
			start++;
			
			if (cur.left != null) {
				queue.add(cur.left);
			}
			if (cur.right != null) {
				queue.add(cur.right);
			}
			
			if (start == end) {
				end = queue.size();  //下一层数量
				start = 0; //start清零
				res.add(layer);
				layer = new ArrayList<Integer>();
				
			}
			
		}
		return res;
		
	}
	
}

猜你喜欢

转载自blog.csdn.net/u010947534/article/details/88736182