二叉树基本知识点

满二叉树和完全二叉树

满二叉树:如果二叉树中除了叶子结点,每个结点的度都为 2,则此二叉树称为满二叉树。

  • 满二叉树中第 i 层的节点数为 2n-1 个。
  • 深度为 k 的满二叉树必有 2k-1 个节点 ,叶子数为 2k-1。
  • 满二叉树中不存在度为 1 的节点,每一个分支点中都两棵深度相同的子树,且叶子节点都在最底层。
  • 具有 n 个节点的满二叉树的深度为 log2(n+1)。

完全二叉树:如果二叉树中除去最后一层节点为满二叉树,且最后一层的结点依次从左到右分布,则此二叉树被称为完全二叉树。

  • 当 i>1 时,父亲结点为结点 [i/2] 。(i=1 时,表示的是根结点,无父亲结点)
  • 如果 2i>n(总结点的个数) ,则结点 i 肯定没有左孩子(为叶子结点);否则其左孩子是结点 2i 。
  • 如果 2i+1>n ,则结点 i 肯定没有右孩子;否则右孩子是结点 2i+1 。

二叉树的遍历

二叉树的先序,中序和后序遍历

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 * }
 */

public class Solution {

    //先序遍历
    void preOrder(TreeNode root,ArrayList<Integer> list1){
        if(root==null){
            return;
        }
        list1.add(root.val);
        preOrder(root.left,list1);
        preOrder(root.right,list1);
    }
    //中序遍历
    void inOrder(TreeNode root,ArrayList<Integer> list2){
        if(root==null){
            return;
        } 
        inOrder(root.left,list2);
        list2.add(root.val);
        inOrder(root.right,list2);
    }
    //后序遍历
    void postOrder(TreeNode root,ArrayList<Integer> list3){
         if(root==null){
            return;
        }
        postOrder(root.left,list3);
        postOrder(root.right,list3);
        list3.add(root.val);
    }
}

二叉树先序中序后序遍历

层序遍历

用队列实现

import java.util.ArrayList;
/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;
    public TreeNode(int val) {
        this.val = val;
    }
}
*/
import java.util.*;
public class Solution {
    ArrayList<Integer> Print(TreeNode pRoot) {
        Queue<TreeNode> queue =new LinkedList();
        ArrayList<Integer> arr=new ArrayList<>();
        queue.add(pRoot);
        TreeNode node;
        while(queue.size()!=0){
            node=queue.poll();
            arr.add(node.val);
            if(node.left!=null) queue.add(node.left);
            if(node.right!=null) queue.add(node.right);
        }
        return arr;
    }
}

二叉树的深度
把二叉树打印成多行
从上往下打印二叉树
按之字形打印二叉树:有一点不同,当为偶数层时,添加的时候用list(index,T)方法,这样T元素会插到index位置,而原index位置以及后面的会自动往后移。这样完成了倒着存储。

二叉搜索树BST(又称二叉排序树、二叉查找树)

一种有序二叉树,如果根节点左子树不为空,则该左子树上的所有节点值都小于根节点的值,如果右子树不为空,则该右子树上的所有节点值都大于该节点的值。如果按中序遍历,则是一个从小到大的有序数组

如何找到前驱节点和后继节点

  • 前驱节点: 左子树的最右(最大)节点
  • 后继节点: 右子树的最左(最小)节点

删除结点

  • 该删除的节点无左右节点:直接删除
  • 该节点有左节点:把左节点赋给该节点的父节点的子节点
  • 该节点有右节点:把右节点赋给该节点的父节点的子节点
  • 该节点有右节点和左节点:
    1、找到该节点的后继节点(右子树的最左节点),把后继节点放在该处,然后删除后继节点(后继节点有可能没有子节点,直接删除,还有可能有右节点,则把右节点赋给该节点的父节点的子节点(同上第三点))
    2、找到该节点的前驱节点(左子树的最右节点),把前驱节点放在该处,然后删除前驱节点(前驱节点有可能没有子节点,直接删除,还有可能有左节点,则把左节点赋给该节点的父节点的子节点(同上第二点))

二叉查找树BST基本实现
图解删除
图解2

刷题
二叉搜索树第k个节点
二叉搜索树的后序遍历

平衡二叉树AVL和红黑树RBT

为什么要有AVL和RBT

大多数二叉排序树BST都是O(h)的时间复杂度,h为树的高度,但对于斜树而言(BST极端情况),BST这些操作时间复杂度将达到O(n),为了保证BST的所有操作的时间复杂度的上限为O(logn) ​,就要想办法把一颗BST树的高度一直维持在O(logn),而AVL和RBT就做到了这一点,AVL和RBT的高度始终都维持在logn,n 为树中的顶点数目。

AVL

  • 每个节点最多只有两个子节点(二叉树)
  • 每个节点的值比它左子树左右节点大2,比它右子树左右节点小(有序)
  • 每个节点左子树与右子树高度差不超过1

旋转

  • 左左:右旋
  • 左右:先左旋再右旋
  • 右右:左旋
  • 右左:先右旋再左旋

AVL

RBT

  • 每个节点不是黑色就是红色
  • 根节点为黑色
  • 红色节点的父节点和子节点不能为红色
  • 所有的叶子节点都是黑色(空节点视为叶子节点NIL)
  • 每个节点到叶子节点的每个路径黑色节点的个数都相等。

每个插入的节点都视为红色

黑高

在一颗红黑树中,从某个结点 x 出发(不包含该结点)到达一个叶结点的任意一条简单路径上包含的黑色结点的数目称为 黑高 ,记为 bh(x) 。
红黑树的黑高则为其根结点的黑高。

变色

  • 如果父节点和叔节点都是红色,则同时变为黑色,然后递归网上变色,根节点为黑色。

旋转

都是父为红,叔为黑的情况

  • 左左:父为左节点,该节点也为左节点,右旋,变色
  • 左右:父为左节点,该节点为右节点,先左旋,再右旋,再变色
  • 右右:父为右节点,该节点也为右节点,左旋,变色
  • 右左:父为右节点,该节点为左节点,先右旋,再左旋,再变色

AVL和RBT的区别

  • AVL左右子树高度不超过1,RBT可能会超过1
  • AVL不平衡进行旋转,RBT不平衡可能只变色,不旋转
  • AVL比RBT更加平衡,AVL在插入和删除时存在大量的选择操作,所以涉及到频繁的插入和删除操作时,应放弃AVL,选择性能更好的红黑树
  • AVL适合查找多,RBT适合修改多

红黑树与平衡二叉树的区别和原理
AVL和RBT

大根堆和小根堆

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值