伸展树的C语言实现

当一个结点被访问时,它很可能不久再被访问到,伸展树就是为了达到这个目的的,其基本想法是通过一系列AVL树的旋转使被访问的结点被放到根上。如果这个结点很深,那么其路径上的许多结点也相对较深,通过重新构造可以使对这些结点的进一步访问花费的时间减少。

代码如下:

  1 #include <iostream>
  2 #include <stdlib.h>
  3 using namespace std;
  4 
  5 struct SplayTreeNode
  6 {
  7     int data;
  8     struct SplayTreeNode* left;
  9     struct SplayTreeNode* right;
 10 };
 11 typedef struct SplayTreeNode* tree;
 12 typedef struct SplayTreeNode* position;
 13 
 14 position rotate_left(position K2);
 15 position rotate_right(position K2);
 16 
 17 //查找
 18 position find(tree T, int x)
 19 {
 20     if (T == NULL)
 21         return NULL;
 22     if (x < T->data)
 23         find(T->left, x);
 24     else if (x > T->data)
 25         find(T->right, x);
 26     else
 27         return T;
 28 }
 29 //插入,返回根节点
 30 position insert(tree &T, int data)
 31 {
 32     if (T == NULL)
 33     {
 34         T = (position)malloc(sizeof(SplayTreeNode));
 35         T->data = data;
 36         T->left = T->right = NULL;
 37     }
 38     else if (data < T->data)
 39         T->left = insert(T->left, data);
 40     else if (data > T->data)
 41         T->right = insert(T->right, data);
 42     
 43     return T;
 44 }
 45 //创建二叉树
 46 tree create_tree(int data[],int n)
 47 {
 48     tree T=NULL;
 49     for (int i = 0; i < n; i++)
 50         insert(T, data[i]);
 51     return T;
 52 }
 53 //判断指针到父结点没,到则返回false,没到返回true
 54 bool pre_data(tree T,int data)
 55 {
 56     if (T->left == NULL)
 57         return T->right->data != data;
 58     else if (T->right == NULL)
 59         return T->left->data != data;
 60     else
 61         return (T->left->data != data && T->right->data != data);
 62 }
 63 //找父节点
 64 position find_parent(tree T, int data)
 65 {
 66     if (T == NULL|| T->data == data)
 67         return NULL;
 68     while (pre_data(T, data))
 69     {
 70         if (data < T->data)
 71             T = T->left;
 72         else if (data > T->data)
 73             T = T->right;
 74     }
 75     return T;
 76 }
 77 //判断是否为之字形(zig-zag)
 78 int zhi(tree T, int data)
 79 {
 80     position p,p1,p2;
 81     p = find(T, data);
 82     p1=find_parent(T,data);
 83     p2 = find_parent(T, p1->data);
 84     if (p2->left == p1 && p1->right == p)
 85         return 1;
 86     else if (p2->right == p1 && p1->left == p)
 87         return 2;
 88     else
 89         return 0;
 90 }
 91 //判断是否为一字形(zig-zig)
 92 int yi(tree T, int data)
 93 {
 94     position p, p1, p2;
 95     p = find(T, data);
 96     p1 = find_parent(T, data);
 97     p2 = find_parent(T, p1->data);
 98     if (p2->left == p1 && p1->left == p)
 99         return 1;
100     else if (p2->right == p1 && p1->right == p)
101         return 2;
102     else
103         return 0;
104 }
105 //avl左单旋
106 position single_left(position K2)
107 {
108     position K1 = K2->left;
109     K2->left = K1->right;
110     K1->right = K2;
111     return K1;
112 }
113 //avl右单旋
114 position single_right(position K2)
115 {
116     position K1 = K2->right;
117     K2 ->right = K1->left;
118     K1->left = K2;
119     return K1;
120 }
121 //avl左右双旋
122 position double_left(position K3)
123 {
124     K3->left = single_right(K3->left);
125     return single_left(K3);
126 }
127 //avl右左双旋
128 position double_right(position K3)
129 {
130     K3->right = single_left(K3->right);
131     return single_right(K3);
132 }
133 //情况1:单旋左
134 position rotate_left(position K2)
135 {
136     position K1 = K2->left;
137     K2->left = K1->left;
138     K1->left = K2->right;
139     K2->right = K1->right;
140     K1->right = K2;
141     return K1;
142 }
143 //情况1:单旋右
144 position rotate_right(position K2)
145 {
146     position K1 = K2->right;
147     K2->right = K1->right;
148     K1->right = K2->left;
149     K2->right = K1->left;
150     K1->left = K2;
151     return K1;
152 }
153 //一字形左
154 position yi_rotate_left(tree T, int data)
155 {
156     position p, p1, p2;
157     p = find(T, data);
158     p1 = find_parent(T, data);
159     p2 = find_parent(T, p1->data);
160     single_left(p2);
161     single_left(p1);
162     return p;
163 }
164 //一字形右
165 position yi_rotate_right(tree T, int data)
166 {
167     position p, p1, p2;
168     p = find(T, data);
169     p1 = find_parent(T, data);
170     p2 = find_parent(T, p1->data);
171     single_right(p2);
172     single_right(p1);
173     return p;
174 }
175 //旋转
176 tree SplayTree_Splay(tree T, int data)
177 {
178     //情况1:data的父结点是树根时,进行单旋
179     if (T == find(T,data) && data < T->data)
180         T=rotate_left(T);
181     else if (T == find(T, data) && data > T->data)
182         T=rotate_right(T);
183     else
184     {
185         position p, p1, p2,p3;
186         p = find(T, data);
187         p1 = find_parent(T, data);
188         p2 = find_parent(T, p1->data);
189         p3 = find_parent(T, p2->data);
190         //情况2:之字形
191         if (zhi(T, data))
192         {
193             switch (zhi(T, data))
194             {
195             case 1:
196                 p = double_left(p2);
197                 if (p3 != NULL)
198                 {
199                     if (p2->data < p3->data)
200                         p3->left = p;
201                     else
202                         p3->right = p;
203                 }
204                 else
205                     T = p;
206                 break;
207             case 2:
208                 p = double_right(p2);
209                 if (p3 != NULL)
210                 {
211                     if (p2->data < p3->data)
212                         p3->left = p;
213                     else
214                         p3->right = p;
215                 }
216                 else
217                     T = p;
218                 break;
219             }
220         }
221         //情况3:一字形
222         else
223         {
224             switch(yi(T,data))
225             {
226             case 1:
227                 p = yi_rotate_left(T, data);
228                 if (p3 != NULL)
229                 {
230                     if (p2->data < p3->data)
231                         p3->left = p;
232                     else
233                         p3->right = p;
234                 }
235                 else
236                     T = p;
237                 break;
238             case 2:
239                 p = yi_rotate_right(T, data);
240                 if (p3 != NULL)
241                 {
242                     if (p2->data < p3->data)
243                         p3->left = p;
244                     else
245                         p3->right = p;
246                 }
247                 else
248                     T = p;
249                 break;
250             }
251         }
252     }
253     return T;
254 }
255 
256 //后序遍历
257 void post_order(tree T)
258 {
259     if (T != NULL)
260     {
261         post_order(T->left);
262         post_order(T->right);
263         cout << T->data << " ";
264     }
265 }
266 
267 int main()
268 {
269     tree T = NULL, T1 = NULL;
270     int data2[] = { 8,4,1,7,5,10,9 };
271     T = create_tree(data2, 7);
272     T1 = create_tree(data2, 7);
273     while (find_parent(T, 1) != NULL)
274         T = SplayTree_Splay(T, 1);
275     post_order(T);
276     cout << endl;
277     while (find_parent(T1, 7) != NULL)
278         T1 = SplayTree_Splay(T1, 7);
279     post_order(T1);
280     system("pause");
281     return 0;
282 }

创建了如下的二叉树:

运行结果(后序遍历):

猜你喜欢

转载自www.cnblogs.com/cs0915/p/12178284.html