美文网首页
平衡二叉树

平衡二叉树

作者: None_Ling | 来源:发表于2017-12-10 23:52 被阅读14次

定义

它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

平衡二叉树

对于一般的二叉搜索树(Binary Search Tree),其期望高度(即为一棵平衡树时)为logn,其各操作的时间复杂度(O(logn))同时也由此而决定。但是,在某些极端的情况下(如在插入的序列是有序的时),二叉搜索树将退化成近似链或链,此时,其操作的时间复杂度将退化成线性的,即O(n)

而平衡二叉树在插入的时候,通过左旋/右旋的方式来保证整颗二叉树的高度不会有太大的差别,从而保证高效的查询效率,时间复杂度保持在O(logN).

左旋

Pivot节点左旋

过程:

  1. 将P节点所在右节点的左子树L接到P节点的右子树R(也就是将Y节点的b子树拼接到Pivot的右子树),修改左子树L的parent以及P节点的右子树指向
  2. 将P节点所在右节点的Parent指向P节点的Parent(将Pivot节点的父节点拼接到Y节点)
  3. 如果P为根节点的话,则替换根节点,如果P节点为父节点的左子树/右子树,则将父节点的左子树/右子树拼接原P节点的右子树R(将P节点的左子树指向Y)
  4. 将原P节点的左子树拼接P节点,并且将P节点的父节点指向替换后的P节点(将Y的左子树拼接到Pivot,并且将Pivot的父节点拼接到Y)

左旋的代码:

    /** From CLR */
    private void rotateLeft(TreeMapEntry<K,V> p) {
        if (p != null) {
            //  获取要旋转节点的右子树节点(即r为上图的Y节点)
            TreeMapEntry<K,V> r = p.right;
            //  将右子树节点的左子树拼接到要旋转节点的右子树上(即将b拼接到Pivot节点的右子树上)
            p.right = r.left;
            //  如果右子树节点的左子树节点不为空的话,则更新该节点的父节点(即将b的父节点指向Pivot节点)
            if (r.left != null)
                r.left.parent = p;
            //  修改右子树节点父节点指向要旋转节点的父节点(将Y节点的Parent指向P节点)
            r.parent = p.parent;
            //  如果要旋转的节点原来没有Parent的话,那就意味着它是根节点,则更新根节点
            if (p.parent == null)
                root = r;
            else if (p.parent.left == p)
            //  如果旋转节点是Parent的左子树的话,则将旋转节点的右子树节点更新到Parent的左子树上(即将P的左子树从原来的指向pivot更新为Y)
                p.parent.left = r;
            else
            //  如果是右子树的话,则将旋转节点的右子树节点更新到Parent的右子树上
                p.parent.right = r;
            //  将旋转节点更新到该节点原右子树的左子树上(即将pivot拼接到Y的左子树上)
            r.left = p;
            //  更新旋转节点的父节点为该节点原右子树(将Pivot节点的parent更新成Y节点)
            p.parent = r;
        }
    }

右旋

Pivot节点右旋

过程:

  1. 将P节点所在左节点的右子树R接到P节点的左子树R(也就是将Y节点的c子树拼接到Pivot的左子树),修改右子树L的parent以及P节点的左子树指向
  2. 将P节点所在左节点的Parent指向P节点的Parent(将Pivot节点的父节点拼接到Y节点)
  3. 如果P为根节点的话,则替换根节点,如果P节点为父节点的左子树/右子树,则将父节点的左子树/右子树拼接原P节点的右子树R(将P的右子树指向Y)
  4. 将原P节点的右子树拼接P节点,并且将P节点的父节点指向替换后的P节点(将Y的右子树拼接到Pivot,并且将Pivot的父节点拼接到Y)
    /** From CLR */
    /** 与左旋逻辑一致,替换即可  **/
    private void rotateRight(TreeMapEntry<K,V> p) {
        if (p != null) {
            TreeMapEntry<K,V> l = p.left;
            p.left = l.right;
            if (l.right != null) l.right.parent = p;
            l.parent = p.parent;
            if (p.parent == null)
                root = l;
            else if (p.parent.right == p)
                p.parent.right = l;
            else p.parent.left = l;
            l.right = p;
            p.parent = l;
        }
    }

常见的不完全平衡二叉树

AVL树
红黑树

相关文章

  • 剑指 offer:39、平衡二叉树

    39. 平衡二叉树 题目描述 输入一棵二叉树,判断该二叉树是否是平衡二叉树。 解题思路: 平衡二叉树:Wiki:在...

  • 平衡二叉树

    1)什么是平衡二叉树?2)平衡二叉树的特点是什么?3)平衡二叉树的构建实现? 一、什么是平衡二叉树?假设有一组数据...

  • 面试题:平衡二叉树

    题目描述 输入一棵二叉树,判断该二叉树是否是平衡二叉树。 知识点 平衡二叉树 Qiang的思路 平衡二叉树是指一个...

  • Leetcode 110 平衡二叉树

    平衡二叉树 题目 给定一个二叉树,判断它是否是高度平衡的二叉树。 本题中,一棵高度平衡二叉树定义为: 一个二叉树每...

  • 二叉树2-平衡二叉树、完全二叉树、二叉树剪枝

    110.平衡二叉树 给定一个二叉树,判断它是否是高度平衡的二叉树。 一棵高度平衡二叉树定义为:一个二叉树每个节点 ...

  • Leetcode题解 - Easy - 4

    110- 平衡二叉树 问题 给定一个二叉树,判断它是否是高度平衡的二叉树。 本题中,一棵高度平衡二叉树定义为: 一...

  • TreeMap源码分析

    TreeMap 平衡二叉树 平衡二叉树(Self-balancing binary search tree)又被称...

  • 图的应用[平衡二叉树以及散列查找]

    平衡⼆二叉树( AVL 树) 平衡⼆二叉树(Self-Balancing Binary Search Tree 或...

  • [LeetCode]110. 平衡二叉树

    110. 平衡二叉树给定一个二叉树,判断它是否是高度平衡的二叉树。本题中,一棵高度平衡二叉树定义为:一个二叉树每个...

  • 力扣算法 - 平衡二叉树

    平衡二叉树 给定一个二叉树,判断它是否是高度平衡的二叉树。本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的...

网友评论

      本文标题:平衡二叉树

      本文链接:https://www.haomeiwen.com/subject/hilbixtx.html