zoukankan      html  css  js  c++  java
  • 平衡树

    一、二叉查找树

      简介

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

      1.二叉查找树的遍历

        在二叉查找树中,从小到大输出结点的值,只需要对二叉树进行中序遍历

    void Print(int u)
    {
        if(!p[u].w) return;
        Print(p[u].lchild);
        printf("%d ",p[u].w);
        Print(p[u].rchild);
        //在二叉查找树中,从小到大输出结点的值,只需要对二叉树进行中序遍历
    }

      2.二叉查找树的查找

        因为二叉查找树是有序的,所以要查找特定的值只需要二分查找即可,如果是非空结点,则查找成功,否则查找失败

    int Find(int u)
    {
        if(!p[u].w) return 0;
        if(p[u].w==find_x) return u;
        if(p[u].w<find_x) return Find(p[u].rchild);        
        if(p[u].w>find_x) return Find(p[u].lchild);
        //因为二叉查找树是有序的,所以要查找特定的值只需要二分查找即可,如果是非空结点,则查找成功,否则查找失败 
    }

      3.二叉查找树查找最值

        找到以u为树根的权值最小的点,此点一定是u的递归操作下的左子树中的叶子结点 

    int Find_Min(int u)
    {
        if(!p[u].w) return 0;
        while(p[p[u].lchild].w) u=p[u].lchild;
        return u;//找到以u为树根的权值最小的点,此点一定是u的递归操作下的左子树中的叶子结点 
    }

      4.二叉查找树中插入结点

        建立在查找的基础上,二分查找,注意的是可能有重复的点,这时候有两个解决方法

          ①插入到左子树中

          ②将结点打计数标记

        假如当前结点为空,建立新的结点,结点的值就是当前插入结点的值,生成左右空子树

    void Insert(int u)
    {
        if(!p[u].w) {p[u].w=insert_x,p[u].cnt++;} 
        if(p[u].w<find_x) return Insert(p[u].rchild);        
        if(p[u].w>find_x) return Insert(p[u].lchild);
        /*假如当前结点为空,建立新的结点,结点的值就是当前插入结点的值,生成左右空子树
        有重复的结点的话,打计数标记解决 */
    } 

      5.二叉查找树中删除结点

        分三种情况讨论

          ①叶子结点

          ②链结点

          ③有两个非空子节点
        前面两个同样对待,用叶子结点代替本身,就等于用空节点代替,等同于删除

        对于第三种情况,删除结点u,要用右子树中最小的值代替

        

    int Delete_Min(int u)
    {
        if(!p[u].lchild) return u;
        else return Delete_Min(p[u].lchild);
        /*如果左子树为空,则直接用自己代替
        否则继续遍历左子树 */
    }
    void Delete(int u)
    {
        if(p[u].w==delete_p)
        {
            if(p[u].cnt>1) {p[u].cnt--;return;}
            if(p[u].rchild&&p[u].lchild)
                p[u]=p[Delete_Min(p[u].rchild)];
            else p[u]=p[p[u].lchild+p[u].rchild];
            return;    
            /*找到值相同的节点,如果节点的cnt>1直接处理返回
            如果发现是链结点或者叶子结点,直接继承两个儿子的序列和的那一个节点
            假使是链节点的话,那么必定有一个结点为空,如果是叶子结点,都为空,就等同与删除了此叶子结点 */
        }    
        if(delete_p<p[u].lchild)  Delete(p[u].lchild);
        else Delete(p[u].rchild);    
    } 

    二、Treap

      1.Treap 旋转(Zig/Zag)

        左旋

        右旋

      2.Treap 插入(Insert)

      3.Treap 删除(erase)

      4.Treap 前驱(Pre)

      5.Treap 后继(next)

      6.Treap 排名(rank)

      7.Treap 第K大(sort)

    三、相关转载于推荐文章(十分感谢这些博主)

  • 相关阅读:
    Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Clien
    docker pull下载镜像报错Get https://registry-1.docker.io/v2/library/centos/manifests/latest:..... timeout
    Maven 插件之 docker-maven-plugin 的使用
    Windows10下的docker安装与入门 (一)使用docker toolbox安装docker
    解决IntelliJ IDEA 创建Maven项目速度慢问题
    svn检出maven项目的步骤
    学习RabbitMQ(三):AMQP事务机制
    TX-LCN分布式事务Demo实战
    SQLite -创建数据库
    备忘录模式
  • 原文地址:https://www.cnblogs.com/SeanOcean/p/11297261.html
Copyright © 2011-2022 走看看