文章目录

  • 二叉树(BS)
  • 二叉查找树(BST)
  • 二叉平衡树(AVL)
  • 红黑树(Red Black Tree)
  • B树(B Tree)
  • 字典树(Trie)
  • 线段树(Segment Tree)
  • 题目实战
    • 144 二叉树的前序遍历
    • 102 二叉树的层次遍历
    • 104 二叉树的最大深度
    • 114 二叉树展开为链表
    • 从中序与后遍历列构造二叉树
    • 从前序与中遍历列构造二叉树
    • 根据前序和后遍历构造二叉树
    • 对称二叉树
    • 450 删除二叉搜索树中的节点
    • 700 二叉搜索树中的搜索
    • 701 二叉搜索树中的插入操作
    • 1361 验证二叉搜索树
    • 530 二叉搜索树的最小绝对差
    • 783 二叉搜索树结点最小距离
    • 108 将有序数组转换为二叉搜索树
    • 二叉搜索树的范围和
    • 二叉搜索树的最近公共祖先
    • 230 二叉搜索树中第 K小的元素
    • 173 二叉搜索树迭代器
    • 99 恢复二叉搜索树
    • 110 平衡二叉树

二叉树(BS)

  • 第i层最多有 2 i 2^i 2i 个结点 ( i = 0 , 1 , 2 ⋯ i = 0, 1 ,2 \cdots i=0,1,2)
  • 高度为h的二叉树至多有 2 ( h + 1 ) − 1 2^{(h + 1)} - 1 2(h+1)1 个结点 ( h = 0 , 1 , 2 ⋯ h = 0, 1 ,2 \cdots h=0,1,2)
  • n 0 n_0 n0 = n 2 n_2 n2 + 1
  • 具有n个结点的完全二叉树的高度为 l o g n logn logn 向下取整
  • 对于完全二叉树,其结点编号 i i i(1 <= i i i <= n)
    • i = 1 i = 1 i=1,根结点,无双亲
    • i > 1 i > 1 i>1 && 2 i < = n 2i <= n 2i<=n,左孩子 2 i 2i 2i
    • i > 1 i > 1 i>1 && 2 i + 1 < = n 2i + 1 <= n 2i+1<=n,右孩子 2 i + 1 2i + 1 2i+1

二叉查找树(BST)

一棵空树,或者是具有下列性质的 二叉树
(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
(3)左、右子树也分别为二叉排序树;
(4)没有键值相等的结点。
(5)它的中序遍历是升序的

二叉平衡树(AVL)

AVL树本质上还是 一棵二叉搜索树,它的特点是

  1. 本身首先是一棵二叉搜索树。
  2. 带有平衡条件:每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1。也就是说,AVL树,本质上是带了平衡功能的二叉查找树(二叉排序树,二叉搜索树)
  3. 删除结点度为0、1、2的结点

红黑树(Red Black Tree)

  1. 红黑树是一种特化的AVL树(平衡二叉树),都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。
  2. 它虽然是复杂的,但它的最坏情况运行时间也是非常良好的,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除,这里的n 是树中元素的数目
  3. LL旋转、RR旋转、LR旋转、RL旋转

B树(B Tree)

#TODO

字典树(Trie)

  1. 又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。
  2. 典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。
  3. 它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。

它有3个基本性质:

  • 根节点不包含字符,除根节点外每一个节点都只包含一个字符
  • 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串
  • 每个节点的所有子节点包含的字符都不相同

线段树(Segment Tree)

  1. 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点
  2. 对于线段树中的每一个非叶子节点[a,b],它的左儿子表示的区间为[a,(a+b)/2],右儿子表示的区间为[(a+b)/2+1,b]。因此线段树是平衡二叉树,最后的子节点数目为N,即整个线段区间的长度
  3. 使用线段树可以快速的查找某一个节点在若干条线段中出现的次数,时间复杂度为O(logN)。而未优化的空间复杂度为2N,因此有时需要离散化让空间压缩

题目实战

144 二叉树的前序遍历

  • https://leetcode-cn.com/problems/binary-tree-preorder-traversal/

中后序遍历如同、递归写法

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    List<Integer> list = new ArrayList<>();

    public List<Integer> preorderTraversal(TreeNode root) {
        if(root == null) return list;
        
        list.add(root.val);
        preorderTraversal(root.left);
        preorderTraversal(root.right);
        return list;
    }
}

非递归写法
手动维护一个栈

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {

    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
	    Stack<TreeNode> stack = new Stack<>();

        TreeNode current = root;
        while (current != null || !stack.isEmpty()) {
            while (current != null) {
                res.add(current.val);
                stack.push(current);
                current = current.left;
            }
            current = stack.pop();
            current = current.right;
        }

        return res;
    }
}

102 二叉树的层次遍历

  • https:/leetcode-cn.com/problems/binary-tree-level-order-traversal/

手动维护一个队列

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
  public List<List<Integer>> levelOrder(TreeNode root) {
    List<List<Integer>> lists = new ArrayList<List<Integer>>();
    if (root == null) return lists;

    Queue<TreeNode> queue = new LinkedList<TreeNode>();
    queue.add(root);
    int level = 0;
    while ( !queue.isEmpty() ) {
      lists.add(new ArrayList<Integer>());
      int len = queue.size();
      for(int i = 0; i < len; ++i) {
        TreeNode node = queue.remove();
        lists.get(level).add(node.val);

        if (node.left != null) queue.add(node.left);
        if (node.right != null) queue.add(node.right);
      }
      level++;
    }
    return lists;
  }
} 

 

104 二叉树的最大深度

  • https:/leetcode-cn.com/problems/maximum-depth-of-binary-tree/
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    int level;
    public int maxDepth(TreeNode root) {
        if(root == null) return 0;
        int maxLeft = maxDepth(root.left);
        int maxRight = maxDepth(root.right);
        return Math.max(maxLeft, maxRight) + 1;
    }
}

114 二叉树展开为链表

  • https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list/
/**
 * Definition for a binary tree node.
 * 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 void flatten(TreeNode root) {
        if(root == null){
            return ;
        }
        //将根节点的左子树变成链表
        flatten(root.left);
        //将根节点的右子树变成链表
        flatten(root.right);
        TreeNode temp = root.right;
        //把树的右边换成左边的链表
        root.right = root.left;
        //记得要将左边置空
        root.left = null;
        //找到树的最右边的节点
        while(root.right != null) root = root.right;
        //把右边的链表接到刚才树的最右边的节点
        root.right = temp;
    }
} 

从中序与后遍历列构造二叉树

  • https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {

    HashMap<Integer,Integer> memo = new HashMap<>();
    int[] post;

    public TreeNode buildTree(int[] inorder, int[] postorder) {
        for(int i = 0;i < inorder.length; i++) memo.put(inorder[i], i);
        post = postorder;
        TreeNode root = buildTree(0, inorder.length - 1, 0, post.length - 1);
        return root;
    }

    public TreeNode buildTree(int is, int ie, int ps, int pe) {
        if(ie < is || pe < ps) return null;

        int root = post[pe];
        int ri = memo.get(root);

        TreeNode node = new TreeNode(root);
        node.left = buildTree(is, ri - 1, ps, ps + ri - is - 1);
        node.right = buildTree(ri + 1, ie, ps + ri - is, pe - 1);
        return node;
    }
} 

从前序与中遍历列构造二叉树

(同上)

根据前序和后遍历构造二叉树

(同上上)

对称二叉树

  • https://leetcode-cn.com/problems/symmetric-tree/

将其转化为回文串问题

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    static StringBuilder sb = new StringBuilder();
    public boolean isSymmetric(TreeNode root) {
        if(root == null) return true;
        preorder(root);
        return isPalindrome(sb);
    }

    public static void preorder(TreeNode root){
        if(root == null) return;
        preorder(root.left);
        sb.append("" + root.val);
        preorder(root.right);
    }

    public static boolean isPalindrome(StringBuilder sb){
        String s1 = sb.toString();
        String s2 = sb.reverse().toString();
        return s1.equals(s2);
    }
}

使用队列(类似BFS的改造)

public boolean isSymmetric(TreeNode root) {
    Queue<TreeNode> q = new LinkedList<>();
    q.add(root);
    q.add(root);
    while (!q.isEmpty()) {
        TreeNode t1 = q.poll();
        TreeNode t2 = q.poll();
        if (t1 == null && t2 == null) continue;
        if (t1 == null || t2 == null) return false;
        if (t1.val != t2.val) return false;
        q.add(t1.left);
        q.add(t2.right);
        q.add(t1.right);
        q.add(t2.left);
    }
    return true;
}

使用递归

public boolean isSymmetric(TreeNode root) {
    return isMirror(root, root);
}

public boolean isMirror(TreeNode t1, TreeNode t2) {
    if (t1 == null && t2 == null) return true;
    if (t1 == null || t2 == null) return false;
    return (t1.val == t2.val)
        && isMirror(t1.right, t2.left)
        && isMirror(t1.left, t2.right);
}

450 删除二叉搜索树中的节点

  • https://leetcode-cn.com/problems/delete-node-in-a-bst/

700 二叉搜索树中的搜索

  • https://leetcode-cn.com/problems/search-in-a-binary-search-tree/

701 二叉搜索树中的插入操作

  • https://leetcode-cn.com/problems/insert-into-a-binary-search-tree/

1361 验证二叉搜索树

  • https://leetcode-cn.com/problems/validate-binary-search-tree

530 二叉搜索树的最小绝对差

https://leetcode-cn.com/problems/minimum-absolute-difference-in-bst


783 二叉搜索树结点最小距离

  • https://leetcode-cn.com/problems/minimum-distance-between-bst-nodes

108 将有序数组转换为二叉搜索树

  • https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree

二叉搜索树的范围和

  • https://leetcode-cn.com/problems/range-sum-of-bst

二叉搜索树的最近公共祖先

  • https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-search-tree

230 二叉搜索树中第 K小的元素

  • https://leetcode-cn.com/problems/kth-smallest-element-in-a-bst

173 二叉搜索树迭代器

  • https://leetcode-cn.com/problems/binary-search-tree-iterator

99 恢复二叉搜索树

  • https://leetcode-cn.com/problems/recover-binary-search-tree

110 平衡二叉树

  • https://leetcode-cn.com/problems/balanced-binary-tree/

你可能感兴趣的:(算法模板总结)