二叉树理论基础
种类
● 满二叉树
○ 一棵二叉树只有度为零和度为二的结点,并且度为零的节点在同一层上,称为满二叉树
○ 深度为k,有2k - 1个节点的二叉树
● 完全二叉树
○ 除底层节点可能没填满,其他都达到最大值,并且最下面一层集中在最左边的位置
○ 堆是完全二叉树
● 二叉搜索树
○ 有序树,左子树小于根,右子树大于根,左右也都是二叉排序树
● 平衡二叉搜索树
○ AVL树,空树或左右子树高度差不超过1,左右子树都是平衡二叉树
存储方式
● 链式存储
○ 通过指针把分布在各个地址的节点串联在一起
● 顺序存储
○ 用数组连续存储,父节点数组下标是i,左子节点是2i + 1,右子节点是2i + 2
遍历方式
● 深度优先遍历
○ 前序中序后序
● 广度优先遍历
定义
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
● 144.二叉树的前序遍历
● 94.二叉树的中序遍历
● 145.二叉树的后序遍历
递归遍历
// 前序遍历
class Solution {
List<Integer> res = new ArrayList();
public List<Integer> preorderTraversal(TreeNode root) {
if (root == null) return res;
res.add(root.val);
preorderTraversal(root.left);
preorderTraversal(root.right);
return res;
}
}
// 中序遍历
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList();
inorder(root, res);
return res;
}
private void inorder(TreeNode root, List<Integer> res) {
if (root == null) return;
inorder(root.left, res);
res.add(root.val);
inorder(root.right, res);
}
}
// 后序遍历
class Solution {
List<Integer> res = new ArrayList();
public List<Integer> postorderTraversal(TreeNode root) {
if (root == null) return res;
postorderTraversal(root.left);
postorderTraversal(root.right);
res.add(root.val);
return res;
}
}
迭代遍历
// 前序遍历,使用栈,先入根,然后循环弹出,再看右左
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList();
Deque<TreeNode> stack = new ArrayDeque();
if (root == null) return res;
stack.addFirst(root);
while (!stack.isEmpty()) {
TreeNode temp = stack.removeFirst();
res.add(temp.val);
if (temp.right != null) stack.addFirst(temp.right);
if (temp.left != null) stack.addFirst(temp.left);
}
return res;
}
}
// 后序遍历,使用栈,和前序遍历类似,先入根,然后循环弹出,再看左右,最后翻转
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList();
Deque<TreeNode> stack = new ArrayDeque();
if (root == null) return res;
stack.addFirst(root);
while (!stack.isEmpty()) {
TreeNode temp = stack.removeFirst();
res.add(temp.val);
if (temp.left != null) stack.addFirst(temp.left);
if (temp.right != null) stack.addFirst(temp.right);
}
Collections.reverse(res);
return res;
}
}
// 中序遍历,稍复杂些,对每个节点,不断找左子节点入栈,直到空,然后出战看一眼右子节点
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList();
Deque<TreeNode> stack = new ArrayDeque();
while (!stack.isEmpty() || root != null) {
while (root != null) {
stack.addFirst(root);
root = root.left;
}
TreeNode temp = stack.removeFirst();
res.add(temp.val);
root = temp.right;
}
return res;
}
}