二叉树
在解题过程中,二叉树的形式通常有两种:满二叉树和完全二叉树。
- 满二叉树:如果一颗二叉树只有度为0和度为2的节点,并且度为0的节点在同一层,这样的树称为满二叉树。满二叉树的深度为k时,节点个数为2^k-1
- 完全二叉树:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点都达到了最大值,并且最下面一层节点都集中在该层最左边的若干位置。若最底层为h层,则该层包含1~2^(h-1)个节点。简而言之——从上到下,从左到右依次填充。
二叉搜索树
- 若它的左子树不为空,则左子树上所有节点的值均小于它的根节点的值
- 若它的右子树不为空,则右子树上所有节点的值均大于它的根节点的值
- 它的左右子树也分别为二叉搜索树
平衡二叉搜索树(AVL树)
它是一颗空树或它的左右两个子树的高度差的绝对值不超过1,并且两个子树都是一颗平衡二叉树
二叉树的存储形式
- 链式存储
- 顺序存储
数组存储二叉树:如果父节点的数组下标为i,则它的左子节点的数组下标为2i+1,右子节点的数组下标为2i+2
二叉树的遍历
- 深度优先遍历(DFS):
- 前序遍历 (中左右)
- 中序遍历 (左中右)
- 后续遍历 (左右中)
- 广度优先遍历(BFS):
- 层序遍历
二叉树的定义
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;
}
}
前序遍历:
- 迭代
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList();
if(root == null)
return list;
Deque<TreeNode> stack = new LinkedList();
TreeNode node = root;
while(node != null || !stack.isEmpty()){
while(node != null){
list.add(node.val);
stack.push(node);
node = node.left;
}
node = stack.pop();
node = node.right;
}
return list;
}
}
- 递归
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList();
preorder(root,list);
return list;
}
public void preorder(TreeNode root,List<Integer> list){
if(root == null){
return;
}
list.add(root.val);
preorder(root.left,list);
preorder(root.right,list);
}
}
中序遍历
- 迭代
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList();
Deque<TreeNode> stack = new LinkedList();
while(!stack.isEmpty() || root != null){
while(root != null){
stack.push(root);
root = root.left;
}
root = stack.pop();
res.add(root.val);
root = root.right;
}
return res;
}
}
- 递归
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList();
inorder(root,res);
return res;
}
public 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 {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList();
if(root == null)
return res;
Deque<TreeNode> stack = new LinkedList();
TreeNode pre = null;
while(!stack.isEmpty() || root != null){
while(root != null){
stack.push(root);
root = root.left;
}
root = stack.pop();
if(root.right == null || root.right == pre){
res.add(root.val);
pre = root;
root = null;
}else{
stack.push(root);
root = root.right;
}
}
return res;
}
}
- 递归
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList();
postorder(root,res);
return res;
}
public void postorder(TreeNode root,List<Integer> res) {
if(root == null)
return;
postorder(root.left,res);
postorder(root.right,res);
res.add(root.val);
}
}
层序遍历
- 迭代
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList();
if(root == null)
return res;
Queue<TreeNode> queue = new LinkedList();
queue.offer(root);
while(!queue.isEmpty()){
List<Integer> list = new ArrayList();
int count = queue.size();
for(int i = 0;i < count;i++){
TreeNode node = queue.poll();
list.add(node.val);
if(node.left != null){
queue.offer(node.left);
}
if(node.right != null){
queue.offer(node.right);
}
}
res.add(list);
}
return res;
}
}
- 递归
class Solution {
List<List<Integer>> res = new ArrayList();
public List<List<Integer>> levelOrder(TreeNode root) {
levelOrder(root,0);
return res;
}
public void levelOrder(TreeNode node,int deep){
if(node == null)
return;
deep++;
if(res.size() < deep){
List<Integer> item = new ArrayList();
res.add(item);
}
res.get(deep-1).add(node.val);
levelOrder(node.left,deep);
levelOrder(node.right,deep);
}
}