二叉查找树BST 模板

二叉查找树BST 就是二叉搜索树 二叉排序树。
就是满足 左儿子<父节点<右儿子 的一颗树,插入和查询复杂度最好情况都是logN的,写起来很简单。
 
根据BST的性质可以很好的解决这些东西
1.查询值
int Search(int k,int x)
{
    if(x<a[k].key && a[k].l) Search(a[k].l,x);
    else if(x>a[k].key && a[k].r) Search(a[k].r,x);
    else return k;    
}

2.查询最小值最大值

int getmin(int k)
{
    if(!a[k].l)return k;
    return getmin(a[k].l);
}
int getmax(int k)
{
    if(!a[k].r)return k;
    return getmax(a[k].r);
}

3.输出排序(其实就是中根遍历)

void Leftorder(int k)
{
    if(a[k].l)Leftorder(a[k].l);
    printf("%d ",a[k].key);
    if(a[k].r)Leftorder(a[k].r); 
}

 

 

 

接下来说一下BST的操作
1.插入
这个没什么好说的,就是小的插右边 大的插左边 递归下去就行了。
void InsertNode(int k,int x)
{
    if(tree_size==0)root=++tree_size,a[root].key=x;
    else if(x<=a[k].key){
        if(a[k].l)InsertNode(a[k].l,x);    
        else{
            tree_size++;
            a[tree_size].key=x;
            a[tree_size].p=k;
            a[k].l=tree_size;    
        }    
    }
    else if(x>a[k].key){
        if(a[k].r)InsertNode(a[k].r,x);    
        else{
            tree_size++;
            a[tree_size].key=x;
            a[tree_size].p=k;
            a[k].r=tree_size;    
        }    
    }
}

2.删除

对于删除点的操作,分下面三种情况:

  (1)删的这个点没有左儿子  ->   让它的右子树代替它

  (2)删的这个点没有右儿子  ->   让它的左子树代替它

  (3)删的这个点子孙齐全   ->   在它的的左子树里选一个最小的(或者在右子树里找一个最大的)放在它的位置,好理解吧

}
void Treeplant(int k,int x,int y)          //用子树y代替x
{
    if(x==root)root=y;
    else if(x==a[a[x].p].l)a[a[x].p].l=y;
    else a[a[x].p].r=y;
    if(a[y].key)a[y].p=a[x].p;
}
void DeleteNode(int k,int x)
{
    if(!a[x].l)Treeplant(k,x,a[x].r);        //情况一
    else if(!a[x].r)Treeplant(k,x,a[x].l);     //情况二
    else{                         //情况三
        int y=getmin(a[x].r);
        if(a[y].p!=x)
        {
            Treeplant(1,y,a[y].r);
            a[y].r=a[x].r,a[a[y].r].p=y;    
        }
        Treeplant(1,x,y);
        a[y].l=a[x].l,a[a[y].l].p=y;
    }
}

这点东西都跟算法导论学的 , 很好理解 ,就扯这么多了 ,立个flag明天写Splay

posted @ 2017-09-19 21:44  Elfish?  阅读(515)  评论(2编辑  收藏  举报