java 二叉树前序(先序)遍历非递归与递归代码总结

二叉树节点的建立
创建二叉树类,其中包含数据域val和存放左右孩子树指针的指针域。

public class TreeNode {
	public int val;
	
	public TreeNode leftChild;
	public TreeNode rightChild;
	
	public TreeNode() {}
	public TreeNode(int val) {
		this.val = val;
	}
}

二叉树的建立
如需了解,请移步:二叉树的层序建立

二叉树的前序遍历递归法
前序遍历顺序为 根 - 左 - 右
首先建立ans数组储存每次遍历得到的树节点的数据,将树的根节点传入递归函数
按照递归思想
1.检查传入根节点是否为空,如果是空则返回
2.将得到的树节点的数据存入ans数组
3.继续向当前节点的左节点递归遍历,直到遍历到最下方的最小子树的左节点为止
4.继续向当前节点的右节点递归遍历,直到遍历到最下方的最小子树的右节点为止

	public static void preorderRecursive(TreeNode root, List<Integer> ans) {
		if (root == null) {
			return;
		}
		ans.add(root.val);
		preorderRecursive(root.leftChild, ans);
		preorderRecursive(root.rightChild, ans);
	}

二叉树前序遍历非递归法
1.先右后左法
此方法运用结构,先存右子树,再存左子树。每次遍历从栈顶弹出一个元素进行遍历检查和输出

  1. 检查根节点是否为空
  2. 将根节点入栈
  3. 进入循环,判断栈是否为空,不为空则弹出栈顶元素cur,并记录cur的数据
  4. 检查cur的右子树,不为空则入栈,为空则开始检查cur的左子树
  5. 检查cur的左子树,不为空则入栈
public static void preorderRecursiveNoI(TreeNode root, List<Integer> ans) {
		if(root == null) return;
		
		Stack<TreeNode> stack = new Stack<TreeNode>();
		stack.push(root);
		
		TreeNode cur;
		while(!stack.isEmpty()) {
			cur = stack.pop();
			ans.add(cur.val);
			
			if(cur.rightChild != null) stack.push(cur.rightChild);
			if(cur.leftChild != null) stack.push(cur.leftChild);
		}	
	}

该方法的技巧在于,每次从栈顶出栈元素a,先检查其右子树和左子树。如果这个元素没有左右子树则继续出栈下一个元素b并对其进行检查,以此类推,直到拿空所有元素。

2.先输出后入栈法
首先持续输出并入栈该树的左子树,达到叶子节点时,出栈并检查其右子树

  1. 检查cur节点是否为空,检查栈是否为空
  2. 如果cur节点为空则跳至第7步
  3. 如果cur节点不为空即从上次循环中取得了左子树或从栈顶元素取得了栈顶元素的右子树
  4. 输出cur的数据,并将cur节点入栈
  5. 取得cur节点的左子树,无左子树则将cur置空
  6. 以上操作输出并入栈了此树的最靠左的所有子树
  7. 如果cur节点为空,则弹出栈顶元素 第一次为最靠左的叶子节点,检查栈顶元素是否存在右子树,进入下一次循环
public static void preorderTraversal(TreeNode root) {
	        Stack<TreeNode> stack = new Stack<>();
	        TreeNode current = root;
	        while (current != null || !stack.isEmpty()) {
	            if (current != null) {
	                System.out.print(current.val + " ");
	                stack.push(current);
	                current = current.leftChild;
	            } else {
	                current = stack.pop().rightChild;
	            }
	        }
	    }

自定义函数在主函数中的用法如下:

List<Integer> ans = new ArrayList<Integer>();
		preorderRecursive(root, ans);
		System.out.print(ans);

完整验证程序如下:

public static void main(String[] args) {
		int[] arr = new int[] { 1, 2, 3, 4, 5, 6 };
		
		TreeNode root = createTree(arr);
		
		List<Integer> ans = new ArrayList<Integer>();
		preorderRecursive(root, ans);
		System.out.print(ans);
	}

正确结果应为:[1, 2, 4, 5, 3, 6]

如有错误或更好的改进意见,欢迎批评指正!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值