1. 程式人生 > >SBT(Size Balanced Tree)

SBT(Size Balanced Tree)

表示 oid 情況 行高 tree 隨機 tar div 復雜

1. 二叉搜索樹

  二叉搜索樹,是一種能實現動態查詢第k大或查詢,某數在序列中的排名的樹形結構,在數據較為隨機的情況下,它的期望復雜度為O(logn),但是若是數據為一個有序序列,那麽該二叉搜索樹,將會變成一條鏈,此時每次查找的復雜度將會變成復雜度為O(n)

2. SBT

  針對上述問題,為了能使復雜度回到O(logn),我們在每次插入操作後,對樹形進行高效的調整使之變的較為平衡。這時樹高變成logn 而搜索的復雜度也於是會變回logn為此我們引入左旋和右旋操作

void zx(int &x)
{
    int y=rs[x];
    rs[x]=ls[y];
    ls[y]
=x; siz[y]=siz[x]; siz[x]=siz[ls[x]]+siz[rs[x]]+1; x=y; }
void yx(int &x)
{
    int y=ls[x];
    ls[x]=rs[y];
    rs[y]=x;
    siz[y]=siz[x];
    siz[x]=siz[ls[x]]+siz[rs[x]]+1;
    x=y;
}

  為了能使樹更加平衡,我們規定該點的左兒子不可以比該點的右兒子的左兒子和右兒子大,用代碼表示起來就是siz[rs[rs[now]]]<=siz[ls[now]]和siz[ls[rs[now]]]<=siz[ls[now]],同理該點的右兒子不可以比該點的左兒子的左兒子和右兒子大。

  為了達到這個目的,我們進行一個maintain操作,對不平衡的子樹進行調整(註:雖然它的復雜度看起來似乎是O(n)但實際上它的復雜度是O(1)的)

void maintain(int &now,int how)
{
    if(how)
    {
        if(siz[rs[rs[now]]]>siz[ls[now]]) zx(now);
        else if(siz[ls[rs[now]]]>siz[ls[now]]) yx(rs[now]),zx(now);
        else return;
    }
    
else { if(siz[ls[ls[now]]]>siz[rs[now]]) yx(now); else if(siz[rs[ls[now]]]>siz[rs[now]]) zx(ls[now]),yx(now); else return; } maintain(ls[now],0); maintain(rs[now],1); maintain(now,0); maintain(now,1); }

接下來的操作都是二叉搜索樹的操作了,加點操作較為簡單,不再贅述

SBT(Size Balanced Tree)