左神算法课第5章_二叉树

在这里插入图片描述

一、二叉树的遍历

1、递归方式
二叉树的遍历采用递归的方式,每一个节点会回到三次(0:57)
先序遍历指的是先打印头节点,再打印左节点,再打印右节点,先序由递归序加工而来,不是第一次不打印(1:05)
中序遍历指的是先打印左节点,再打印头节点,再打印右节点,不是第二次不打印
后序遍历指的是先打印右节点,再打印左节点,不是第三次不打印

	public static void preOrderRecur(Node head) {
		if (head == null) {
			return;
		}
		System.out.print(head.value + " ");
		preOrderRecur(head.left);
		preOrderRecur(head.right);
	}

	public static void inOrderRecur(Node head) {
		if (head == null) {
			return;
		}
		inOrderRecur(head.left);
		System.out.print(head.value + " ");
		inOrderRecur(head.right);
	}

	public static void posOrderRecur(Node head) {
		if (head == null) {
			return;
		}
		posOrderRecur(head.left);
		posOrderRecur(head.right);
		System.out.print(head.value + " ");
	}

2、非递归怎么实现
任何递归函数都可以改成非递归函数
准备一个栈,先把头节点放到栈里去
先序遍历:

  1. 从栈中弹出一个节点cur
  2. 打印(处理)cur
  3. 先压右再压左
	public static void preOrderUnRecur(Node head) {
		System.out.print("pre-order: ");
		if (head != null) {
			Stack<Node> stack = new Stack<Node>();
			stack.add(head);
			while (!stack.isEmpty()) {
				head = stack.pop();
				System.out.print(head.value + " ");
				if (head.right != null) {
					stack.push(head.right);
				}
				if (head.left != null) {
					stack.push(head.left);
				}
			}
		}
		System.out.println();
	}

后序遍历:
准备两个栈,一个收集栈

  1. 弹出一个节点cur
  2. cur放入收集栈
  3. 先左再右压栈
  4. 收集完了再打印就是后序
	public static void posOrderUnRecur1(Node head) {
		System.out.print("pos-order: ");
		if (head != null) {
			Stack<Node> s1 = new Stack<Node>();
			Stack<Node> s2 = new Stack<Node>();
			s1.push(head);
			while (!s1.isEmpty()) {
				head = s1.pop();
				s2.push(head);
				if (head.left != null) {
					s1.push(head.left);
				}
				if (head.right != null) {
					s1.push(head.right);
				}
			}
			while (!s2.isEmpty()) {
				System.out.print(s2.pop().value + " ");
			}
		}
		System.out.println();
	}

中序遍历(左-右-头)(1:24):
准备一个栈,每棵子树,整棵树左边界进栈,依次弹出的过程中打印,对弹出节点的右树重复。

	public static void inOrderUnRecur(Node head) {
		System.out.print("in-order: ");
		if (head != null) {
			Stack<Node> stack = new Stack<Node>();
			while (!stack.isEmpty() || head != null) {
				if (head != null) {
					stack.push(head);
					head = head.left;//左边全部压栈
				} else {
					head = stack.pop();
					System.out.print(head.value + " ");//弹出就打印
					head = head.right;//换到右边的节点,继续把这个节点的左边界全压栈
				}
			}
		}
		System.out.println();
	}

二叉树递归和非递归的遍历,必须自己练会。

3、如何直观地打印一个二叉树(就是为了看看图)

具体见文件:

Code02_PrintBinaryTree

4、宽度优先遍历

对于二叉树来说先序遍历就是深度优先遍历,宽度优先遍历就是一层一层打印
准备一个队列,头进尾出也就是先进先出,弹出一个打印一个,先放左再放右,即可实现宽度优先遍历。
用哈希表的方法(1:58)
新手看代码不能硬看,准备纸和笔,人家用什么变量名你就写一模一样的在纸上,一步一步抠。
不用哈希表的方法比用哈希表的方法难得多(2:11)。

二、二叉树的相关概念及其实现判断

在这里插入图片描述

  1. 搜索二叉树指的是根节点比左子节点大,比右子节点小,对于每一个子树都成立。一个简单的办法是中序遍历之后得到的是升序。把中序遍历中打印的环节改成判断的环节即可。
  2. 完全二叉树指的是每一层全都是满的,即使最后一层不满,也是从左到右依次变满的。按宽度遍历,在依次遍历到每个节点的过程中如果有右子节点没有左子节点,直接返回false。如果没有有右无左的节点,遇到了第一个左右子不全的节点,那么后续全为叶节点才为完全二叉树(0:21)。
  3. 满二叉树,统计最大深度L,统计节点个数N,N=2^L-1
  4. 平衡二叉树指的是对于任何一个子树来说,左数和右树的高度差不超过1(0:37)。判断一个节点以下构成的子树为平衡二叉树,首先左子树为平衡二叉树,右子树为平衡二叉树,左子树高度和右子树高度差小于1。

!递归结构可以解决一切面试中的树型DP问题!

三、给定两个二叉树的节点node1和node2,找到他们的最低公共祖先节点

1:19

四、

1:48
在这里插入图片描述

五、

2:02
在这里插入图片描述

六、

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值