C++实现的avl平衡树
1 #include <stdlib.h>
2 #include <time.h>
3 #include <string.h>
4 #include <vector>
5 #include <stdio.h>
6
7 using namespace std;
8
9 class AvlNode
10 {
11 public :
12 int data;
13 AvlNode *parent;
14 AvlNode *left;
15 AvlNode *right;
16 int height;
17 int cx;
18 int cy;
19 AvlNode()
20 {
21 left = right = parent = NULL;
22 height = 1;
23 cx = cy = data = 0;
24 }
25
26 };
27
28 class AvlTree
29 {
30 public :
31 AvlNode *root;
32 void rotateR(AvlNode *node);
33 void rotateL(AvlNode *node);
34 int getChildHeight(AvlNode *node);
35 int getNodeHeight(AvlNode *node);
36 int getBal(AvlNode *node);
37 void recallBalancing(AvlNode *node);
38 void insertValue(const int value);
39 void preTravel(const AvlNode *node,vector<int> &vec);
40 void postTravel(const AvlNode *node, vector<int> &vec);
41 void midTravel(const AvlNode *node, vector<int> &vec);
42 AvlTree() : root(NULL) {} ;
43 };
44
45
46 int AvlTree::getNodeHeight(AvlNode *node)
47 {
48 if (node == NULL) return 0;
49 return getNodeHeight(node->left) - getNodeHeight(node->right);
50 }
51
52 static inline int Max(const int a, const int b)
53 {
54 return (a>b)?a:b;
55 }
56
57 int AvlTree::getBal(AvlNode *node)
58 {
59 if (node == NULL) return 0;
60 return getNodeHeight(node->left) - getNodeHeight(node->right);
61 }
62
63 void AvlTree::preTravel(const AvlNode *node, vector<int> &vec)
64 {
65 if (node == NULL) return;
66 vec.push_back(node->data);
67 preTravel(node->left, vec);
68 preTravel(node->right, vec);
69 }
70
71 void AvlTree::midTravel(const AvlNode *node, vector<int> &vec)
72 {
73 if (node == NULL) return;
74 midTravel(node->left, vec);
75 vec.push_back(node->data);
76 midTravel(node->right, vec);
77 }
78
79 void AvlTree::postTravel(const AvlNode *node, vector<int> &vec)
80 {
81 if (node == NULL) return;
82 postTravel(node->left, vec);
83 postTravel(node->right, vec);
84 vec.push_back(node->data);
85 }
86
87 void AvlTree::insertValue(const int value)
88 {
89 AvlNode *cursor = root;
90 if (cursor == NULL) {
91 AvlNode *node = new AvlNode;
92 node->data = value;
93 root = node;
94 return;
95 }
96
97 int ret;
98 //printf("begin while
");
99 while (cursor != NULL) {
100 ret = cursor->data;
101 // printf("%d %d
",value,ret);
102 if (value < ret) {
103 if (cursor->left == NULL) {
104 AvlNode *node = new AvlNode;
105 node->data = value;
106 node->parent = cursor;
107 cursor->left = node;
108 break;
109 }
110 cursor = cursor->left;
111 }
112 else if (value > ret) {
113 if (cursor->right == NULL) {
114 AvlNode *node = new AvlNode;
115 node->data = value;
116 node->parent = cursor;
117 cursor->right = node;
118 break;
119 }
120 cursor = cursor->right;
121 }
122 else {
123 return;
124 }
125 } // while
126 recallBalancing(cursor);
127 }
128
129
130
131 int AvlTree::getChildHeight(AvlNode *node)
132 {
133 return Max(getNodeHeight(node->left), getNodeHeight(node->right));
134 }
135
136 void AvlTree::recallBalancing(AvlNode *node)
137 {
138 AvlNode *cursor = node;
139 int bal;
140 // printf("Begin balancing
");
141 while (cursor != NULL)
142 {
143 bal = getBal(cursor);
144 if (bal == 0) {
145 return;
146 }
147 else if (bal == -1 || bal == 1) {
148 cursor->height = getChildHeight(cursor) + 1;
149 cursor = cursor->parent;
150 }
151 else if (bal > 1) {
152 bal = getBal(cursor->left);
153 if (bal < 0)
154 rotateL(cursor->left);
155 rotateR(cursor);
156 return;
157 }
158 else {
159 bal = getBal(cursor->right);
160 if (bal > 0)
161 rotateR(cursor->right);
162 rotateL(cursor);
163 return;
164 }
165 }
166 // printf("End balance
");
167 }
168
169
170 void AvlTree::rotateL(AvlNode *node)
171 {
172 AvlNode*pivot = node->right;
173 pivot->height = node->height;
174 node->height--;
175 AvlNode*parent = node->parent;
176
177 node->right = pivot->left;
178 if (pivot->left)
179 pivot->left->parent = node;
180 pivot->left = node;
181 node->parent = pivot;
182
183 pivot->parent = parent;
184 if (parent)
185 {
186 if (parent->left == node)
187 parent->left = pivot;
188 else parent->right = pivot;
189 }
190 else
191 {
192 // parent == NULL retur new root
193 root = pivot;
194 }
195 }
196
197 void AvlTree::rotateR(AvlNode *node)
198 {
199 AvlNode*pivot = node->left;
200 pivot->height = node->height;
201 node->height--;
202 AvlNode*parent = node->parent;
203
204 node->left = pivot->right;
205 if (pivot->right)
206 pivot->right->parent = node;
207 pivot->right = node;
208 node->parent = pivot;
209
210 pivot->parent = parent;
211 if (parent)
212 {
213 if (parent->left == node)
214 parent->left = pivot;
215 else parent->right = pivot;
216 }
217 else
218 {
219 // parent == NULL retur new root
220 root = pivot;
221 }
222 }
223
224
225
226 int main(int argc,char **argv)
227 {
228 AvlTree avltree;
229 vector<int> vec;
230
231 srand(time(NULL));
232 int i;
233 for (i=0; i < 32; i++)
234 avltree.insertValue(rand()%999);
235 avltree.midTravel(avltree.root, vec);
236 for (auto elem : vec) {
237 printf("%d ", elem);
238 }
239
240 return 0;
241 }