首页 > 代码库 > Splay伸展树

Splay伸展树

伸展树,感觉对我这种菜鸟还是有些吃力,主要也是旋转的时候吧,把要查询的节点旋转到根节点,看网上是有两种方法,一是从上到下,一是从下到上。从上到下,是把树拆分成中树,左树和右树,始终保证目标节点在中树,不断向下把中树的节点添到右树或者左树,直到目标节点为中树的根,再将三树合并起来。另外一种从下到上,旋转操作类似AVL树中的旋转,但是判断好像不是很好写,我写的是从上到下的,另外删除也很巧妙,先把目标节点旋转到根,若此时左子树为空直接删除,否则找到左子树最右的节点当头,利用伸展树的特殊旋转就可以一步删除,太牛叉了,还有就是一个元素和指向它的指针的巧妙运用,真是涨了不少知识啊,,,,

技术分享
  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <stdlib.h>
  4 
  5 typedef struct _spaly
  6 {
  7     int key;
  8     struct _spaly* left;
  9     struct _spaly* right;
 10 }*Pspaly;
 11 
 12 Pspaly splay(Pspaly tree,int k);
 13 void Destory(Pspaly tree);
 14 void Printf(Pspaly tree);
 15 Pspaly Insert(Pspaly tree,int k);
 16 Pspaly Node(int k);
 17 Pspaly Delete(Pspaly tree,int k);
 18 Pspaly Search(Pspaly tree,int k);
 19 
 20 int main()
 21 {
 22     Pspaly tree=NULL;
 23     tree = Insert(tree,3);
 24     tree = Insert(tree,6);
 25     tree = Insert(tree,1);
 26     tree = Insert(tree,5);
 27     tree = Insert(tree,7);
 28     tree = Insert(tree,0);
 29     tree = Insert(tree,11);
 30     Printf(tree);
 31     printf("\n");
 32     tree=splay(tree,2);
 33      Printf(tree);
 34      printf("\n");
 35     // tree = splay(tree,6);
 36      tree = Delete(tree,3);
 37      Printf(tree);
 38       printf("\n");
 39      tree = splay(tree,11);
 40       Printf(tree);
 41     return 0;
 42 }
 43 
 44 Pspaly Node(int k)
 45 {
 46     Pspaly node = (Pspaly)malloc(sizeof(_spaly));
 47     node->key = k;
 48     node->left = NULL;
 49     node->right = NULL;
 50     return node;
 51 }
 52 
 53 Pspaly Insert(Pspaly tree,int k)
 54 {
 55     Pspaly node = Node(k);
 56     if(tree==NULL)
 57     {
 58         tree = node;
 59         return tree;
 60     }
 61     if(k<tree->key)
 62     {
 63         tree->left = Insert(tree->left,k);
 64     }
 65     else if(k>tree->key)
 66     {
 67         tree->right = Insert(tree->right,k);
 68     }
 69     return tree;
 70 }
 71 
 72 //销毁伸展树
 73 void Destory(Pspaly tree)
 74 {
 75     if(tree==NULL)return;
 76     Destory(tree->left);
 77     Destory(tree->right);
 78     free(tree);
 79 }
 80 
 81 //核心,旋转操作
 82 Pspaly splay(Pspaly tree,int k)
 83 {
 84     Pspaly l,r;
 85     _spaly N;
 86     l = r = &N; //  
 87     while(true)
 88     {
 89         if(k<tree->key)
 90         {
 91             if(tree->left==NULL)
 92                 break;//当目标节点不在树上时,在删除时有大用
 93             if(k<tree->left->key)
 94             {
 95                 Pspaly tem = tree->left;
 96                 tree->left = tem->right;
 97                 tem->right = tree;
 98                 tree = tem;
 99             }
100             //将节点加到右树
101             r->left = tree; 
102             r = tree;
103             tree = tree->left;
104         }
105         else if(k>tree->key)
106         {
107             if(tree->right==NULL)break;
108             if(k>tree->right->key)
109             {
110                 Pspaly tem = tree->right;
111                 tree->right = tem->left;
112                 tem->left = tree;
113                 tree = tem;
114             }
115             l->right = tree;
116             l = tree;
117             tree = tree->right;
118         }
119         else
120         {
121             break;
122         }
123 
124     }
125     
126     //合并三课树
127         l->right = tree->left;
128         r->left = tree->right;
129         tree->left = N.right;
130         tree->right = N.left;
131         return tree;
132 }
133 
134 //打印函数
135 void Printf(Pspaly tree)
136 {
137     if(tree==NULL)return;
138     printf("父亲结点是:%d",tree->key);
139     printf(" 左儿子是:");
140     if(tree->left==NULL)printf("NULL");
141     else printf("%d",tree->left->key);
142     printf(" 右儿子是:");
143     if(tree->right==NULL)printf("NULL\n");
144     else printf("%d\n",tree->right->key);
145     Printf(tree->left);
146     Printf(tree->right);
147 }
148 
149 Pspaly Delete(Pspaly tree,int k)
150 {
151     Pspaly tem;
152     if(Search(tree,k)==NULL)
153     {
154         printf("无\n");
155         return NULL;
156     }
157     tree = splay(tree,k);
158     if(tree->left==NULL)
159         return tree->right;
160     else
161     {
162         //将tree->left的最右子树当做根
163       tem = splay(tree->left,k);
164       tem->right = tree->right;
165     }
166     free(tree);
167     return tem;
168 }
169 
170 Pspaly Search(Pspaly tree,int k)
171 {
172     if(tree==NULL)return NULL;
173     if(k<tree->key)Search(tree->left,k);
174     else if(k>tree->key)Search(tree->right,k);
175     else
176         return tree;
177 }
View Code

 

Splay伸展树