自从看懂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;
}