zoukankan      html  css  js  c++  java
  • 树旋转学习笔记

    平衡树树旋转

    代码

    inline void left_rotate(int &node)
    {
        int r=tree[node].r;
        tree[node].r=tree[r].l;
        tree[r].l=node;
        node=r;
    }
    inline void right_rotate(int &node)
    {
        int l=tree[node].l;
        tree[node].l=tree[l].r;
        tree[l].r=node;
        node=l;
    }
    

    分析

    先上一张树旋转的示意图

    树旋转

    图片来自《算法导论》 $ ext{P176 13.2}$ 旋转

    树旋转的作用

    树旋转是平衡树上用于维护平衡树平衡的基本操作,有左旋和右旋两种操作

    旋转过程分析

    在进行树旋转时需要维护好二叉搜索树的性质,即

    对于每棵子树,都有:

    左 < 根 < 右

    再看《算法导论》中描述旋转的图片。

    以右旋为例,旋转后$ ext{x}$代替$ ext{y}$作为子树的根节点,由于原来$ ext{x}$在$ ext{y}$的左子树上,所以旋转最后$ ext{y}$在$ ext{x}$的右子树上;

    而旋转前$ ext{x}$的左子树$alpha$的根节点则一定小于$ ext{x}$和$ ext{y}$,所以旋转后$alpha$仍在$ ext{x}$的左子树上;

    而$ ext{x}$的右子树$eta$的根节点则可以看出来是$ ext{x} < eta < ext{y}$的一种关系,所以旋转后在$ ext{y}$的左子树上;

    至于$ ext{y}$的右子树$gamma$则与$ ext{x}$的左子树$alpha$类似,这里不再阐述。

    代码分析

    以左旋为例:

    int r=tree[node].r;
    

    先将node节点的右子树另外保存,同swap函数的t变量类似。

    tree[node].r=tree[r].l;
    

    将图中$ ext{x}$节点的右子树$ ext{y}$节点改为$ ext{y}$节点的左子树$eta$

    tree[r].l=node;
    

    将图中$ ext{y}$节点的左子树改为$ ext{x}$节点

    node=r;
    

    最后把正在旋转的子树的根节点改为$ ext{y}$

    参考文献

    1. 【AgOHの数据结构】平衡树专题之叁 树旋转与AVL树

    2. 《算法导论》 $ ext{P176 13.2}$ 旋转

    3. Github/StableAgOH/Codebase-for-AgOH

  • 相关阅读:
    web.config配置错误的后果
    重装VS.NET碰到:IDE 未能加载 Dte.olb
    初次使用Wix
    typedef
    [WTL] Accelerator
    在浏览器中粘贴时替换剪贴板数据
    自定义浏览器
    关于MSHTML
    [WTL] STLport安装指南
    [WTL] WTL7.5中CFileDialog用'\0'过滤
  • 原文地址:https://www.cnblogs.com/XZDXRZ/p/12390388.html
Copyright © 2011-2022 走看看