当一个结点被访问时,它很可能不久再被访问到,伸展树就是为了达到这个目的的,其基本想法是通过一系列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 }
创建了如下的二叉树:

运行结果(后序遍历):

来源:https://www.cnblogs.com/cs0915/p/12178284.html