forked from imxtx/algorithms
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathavl.c
173 lines (156 loc) · 3.52 KB
/
avl.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#include <stdio.h>
#include <stdlib.h>
// 树节点定义
typedef struct Node
{
int key;
struct Node *left;
struct Node *right;
int height;
} Node;
// 辅助函数:比大小
int max(int a, int b)
{
return a > b ? a : b;
}
// 辅助函数:计算树的高度
int height(Node *root)
{
if (root == NULL)
return 0;
return 1 + max(height(root->left), height(root->right));
}
// 辅助函数:创建新节点
Node *newNode(int key)
{
Node *node = (Node *)malloc(sizeof(Node));
node->key = key;
node->left = NULL;
node->right = NULL;
node->height = 0;
return node;
}
// 辅助函数:获得节点的平衡因子
int getBalanceFactor(Node *node)
{
if (node == NULL)
return 0;
return height(node->left) - height(node->right);
}
// 右旋
Node *rightRotate(Node *y)
{
/* 树结构示意图:
y
/ \
x O
/ \
O O
*/
Node *x = y->left;
Node *xr = x->right;
// 旋转
x->right = y;
y->left = xr;
// 更新节点的高度
x->height = height(x);
y->height = height(y);
// 返回旋转后的根节点
return x;
}
// 左旋
Node *leftRotate(Node *y)
{
/* 树结构示意图:
y
/ \
O x
/ \
O O
*/
Node *x = y->right;
Node *xl = x->left;
// 旋转
x->left = y;
y->right = xl;
// 更新节点的高度
x->height = height(x);
y->height = height(y);
// 返回旋转后的根节点
return x;
}
/**
* @brief 向以node为根节点的树中插入key
*
* @param node 根节点
* @param key 插入值
* @return Node* 插入后该树的新的根节点
*/
Node *insert(Node *node, int key)
{
// 1. 按照BST的方法在叶节点上插入新值
if (node == NULL)
return newNode(key);
if (key < node->key)
node->left = insert(node->left, key);
else if (key > node->key)
node->right = insert(node->right, key);
else
return node; // 值已经存在
// 2. 更新插入路径上每棵子树的高度
node->height = height(node);
// 3. 计算平衡因子,不平衡则需要调整
int bf = getBalanceFactor(node);
// LL型不平衡
if (bf > 1 && key < node->left->key)
return rightRotate(node);
// RR型不平衡
if (bf < -1 && key > node->right->key)
return leftRotate(node);
// LR型不平衡
if (bf > 1 && key > node->left->key)
{
node->left = leftRotate(node->left);
return rightRotate(node);
}
// RL型不平衡
if (bf < -1 && key < node->right->key)
{
node->right = rightRotate(node->right);
return leftRotate(node);
}
// 如果是平衡的直接返回根节点
return node;
}
// 辅助函数:输出树的先序遍历
void preOrder(Node *root)
{
if (root != NULL)
{
printf("%d ", root->key);
preOrder(root->left);
preOrder(root->right);
}
}
int main(int argc, char const *argv[])
{
struct Node *root = NULL;
/* 测试,最终树结构应该如下图所示:
30
/ \
20 40
/ \ \
10 25 50
*/
root = insert(root, 10);
root = insert(root, 20);
root = insert(root, 30);
root = insert(root, 40);
root = insert(root, 50);
root = insert(root, 25);
printf(
"Preorder traversal of the constructed AVL tree is \n");
preOrder(root);
putchar('\n');
return 0;
}