splay_tree学习+模板

自从看懂splay_tree(也有叫spaly_tree)后,昨晚敲了第一发281行,已经被恶心死,难倒是不难,就是细节,看了大牛的博客,本想自己总结一发,结果图不好弄,我差不多已经是个废C~K了,先学AVL,懂了后看splay_tree就很容易了,无非就是多加了几种旋转,注意分解合并,splay_tree可能单次查询不如AVL,但是大量查询并且多次重复查询的时候他就比AVL快了好多,可以说多次查询后深度越小,被查询的频率越高。

今天splay_tree已经被我优化到了二百四十多行了,但还是不亚于一个模拟。。

放上大牛的链接+我的splay_tree模板。

http://www.cnblogs.com/vamei/archive/2013/03/24/2976545.html

http://blog.csdn.net/pacosonswjtu/article/details/50609414

代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;
typedef struct node *position;
typedef int ElementTP;
struct node{
    position parent;
    ElementTP element;
    position lchild;
    position rchild;
};
typedef struct node *TREE;

TREE find_value(TREE,ElementTP);
position insert_value(TREE,ElementTP);
static void splay_tree(TREE,position);
static position search_value(TREE,ElementTP);
static void with_grandpa(TREE,position);

static void insert_node_to_nonempty_tree(TREE,position);
static TREE left_single_rotate(TREE);
static TREE left_double_rotate(TREE);
static TREE right_single_rotate(TREE);
static TREE right_double_rotate(TREE);
static TREE left_zig_zig(TREE);
static TREE right_zig_zig(TREE);
int main(){
    TREE tr;
    tr=NULL;
    tr=insert_value(tr,6);
    tr=insert_value(tr,5);
    tr=insert_value(tr,4);
    tr=insert_value(tr,3);
    tr=insert_value(tr,1);
    tr=insert_value(tr,2);

    tr=find_value(tr,2);
    printf("%d\n",tr->rchild->lchild->element);
    return 0;
}
position insert_value(TREE tr,ElementTP value){
    position np;
    np=(position)malloc(sizeof(struct node));
    np->element=value;
    np->parent=NULL;
    np->lchild=NULL;
    np->rchild=NULL;

    if(tr==NULL)
        tr=np;
    else{
        insert_node_to_nonempty_tree(tr,np);
    }
    return tr;
}
TREE find_value(TREE tr,ElementTP value){
    position np;
    np=search_value(tr,value);
    if(np!=NULL&&np!=tr){
        splay_tree(tr,np);
    }
    return np;
}
static void splay_tree(TREE tr,position np){
    while(np->parent!=NULL){
        if(np->parent->parent!=NULL){
            with_grandpa(tr,np);
        }
        else if(tr->lchild==np){
            right_single_rotate(tr);
        }
        else if(tr->rchild==np){
            left_single_rotate(tr);
        }
    }
}
static void with_grandpa(TREE tr,position np){
    position parent,grandpa;
    int i,j;

    parent=np->parent;
    grandpa=parent->parent;

    i=(grandpa->lchild==parent)?-1:1;
    j=(parent->lchild=np)?-1:1;
    if(i==-1&&j==1){
        right_double_rotate(grandpa);
    }
    else if(i==1&&j==-1){
        left_double_rotate(grandpa);
    }
    else if(i==-1&&j==-1){
        right_zig_zig(grandpa);
    }
    else{
        left_zig_zig(grandpa);
    }
}
static position search_value(TREE tr,ElementTP value){
    if(tr==NULL){
        return NULL;
    }
    if(tr->element==value){
        return tr;
    }
    else if(value<tr->element){
        return search_value(tr->lchild,value);
    }
    else{
        return search_value(tr->rchild,value);
    }
}
static TREE left_single_rotate(TREE tr){
    TREE newRoot,parent;
    parent=tr->parent;
    newRoot=tr->rchild;
    if(newRoot->lchild!=NULL)
        newRoot->lchild->parent=tr;
    tr->rchild=newRoot->lchild;
    newRoot->lchild=tr;
    newRoot->parent=parent;
    if(parent!=NULL){
        if(parent->lchild==tr){
            parent->lchild=newRoot;
        }
        else{
            parent->rchild=newRoot;
        }
    }
    tr->parent=newRoot;
    return newRoot;
}
static TREE right_single_rotate(TREE tr){
    TREE newRoot,parent;
    parent=tr->parent;
    newRoot=tr->lchild;
    if(newRoot->rchild!=NULL)
        newRoot->rchild->parent=tr;
    tr->lchild=newRoot->rchild;
    newRoot->rchild=tr;
    newRoot->parent=parent;
    if(parent!=NULL){
        if(parent->lchild==tr){
            parent->lchild=newRoot;
        }
        else{
            parent->rchild=newRoot;
        }
    }
    tr->parent=newRoot;
    return newRoot;
}
static TREE left_double_rotate(TREE tr){
    right_single_rotate(tr->rchild);
    return left_single_rotate(tr);
}
static TREE right_double_rotate(TREE tr){
    left_single_rotate(tr->lchild);
    return right_single_rotate(tr);
}
static void insert_node_to_nonempty_tree(TREE tr,position np){
    if(np->element<=tr->element){
        if(tr->lchild==NULL){
            tr->lchild=np;
            np->parent=tr;
            return ;
        }
        else{
            insert_node_to_nonempty_tree(tr->lchild,np);
        }
    }
    else if(np->element>tr->element){
        if(tr->rchild==NULL){
            tr->rchild=np;
            np->parent=tr;
            return ;
        }
        else{
            insert_node_to_nonempty_tree(tr->rchild,np);
        }
    }
}
static TREE right_zig_zig(TREE tr){
    position parent,middle,newRoot;
    parent=tr->parent;
    middle=tr->lchild;
    newRoot=tr->lchild->lchild;

    tr->lchild=middle->rchild;
    if(middle->rchild!=NULL)
        middle->rchild->parent=tr;
    middle->rchild=tr;
    tr->parent=middle;
    middle->lchild=newRoot->rchild;
    if(newRoot->rchild!=NULL)
        newRoot->rchild->parent=middle;

    newRoot->rchild=middle;
    middle->parent=newRoot;

    newRoot->parent=parent;
    if(parent!=NULL){
        if(parent->lchild==tr){
            parent->lchild=newRoot;
        }
        else{
            parent->rchild=newRoot;
        }
    }
    return newRoot;
}
static TREE left_zig_zig(TREE tr){
    position parent,middle,newRoot;
    parent=tr->parent;
    middle=tr->rchild;
    newRoot=tr->rchild->rchild;

    tr->rchild=middle->lchild;
    if(middle->lchild!=NULL)
        middle->lchild->parent=tr;

    middle->lchild=tr;
    tr->parent=middle;

    middle->rchild=newRoot->lchild;
    if(newRoot->lchild!=NULL)
        newRoot->lchild->parent=middle;

    newRoot->lchild=middle;
    middle->parent=newRoot;

    newRoot->parent=parent;
    if(parent!=NULL){
        if(parent->rchild==tr){
            parent->rchild=newRoot;
        }
        else{
            parent->lchild=newRoot;
        }
    }
    return newRoot;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值