数据结构系列19 - 平衡二叉树 - 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
/*************************************************************************
* File Name: avlTree.c
* Author: TyrantLucifer
* E-mail: TyrantLucifer@gmail.com
* Blog: https://tyrantlucifer.com
* Created Time: Sat 17 Jul 2021 06:24:32 PM CST
************************************************************************/
#include <stdio.h>
#include <stdlib.h>

typedef struct TreeNode {
int data;
int height;
struct TreeNode* lchild;
struct TreeNode* rchild;
}TreeNode;

int getHeight(TreeNode* node) {
return node ? node -> height : 0;
}

int max(int a, int b) {
return a > b ? a : b;
}

void rrRotation(TreeNode* node, TreeNode** root) {
TreeNode* temp = node -> rchild;
node -> rchild = temp -> lchild;
temp -> lchild = node;
node -> height = max(getHeight(node -> lchild), getHeight(node -> rchild)) + 1;
temp -> height = max(getHeight(temp -> lchild), getHeight(temp -> rchild)) + 1;
*root = temp;
}

void llRotation(TreeNode* node, TreeNode** root) {
TreeNode* temp = node -> lchild;
node -> lchild = temp -> rchild;
temp -> rchild = node;
node -> height = max(getHeight(node -> lchild), getHeight(node -> rchild)) + 1;
temp -> height = max(getHeight(temp -> lchild), getHeight(temp -> rchild)) + 1;
*root = temp;
}

void avlInsert(TreeNode** T, int data) {
if (*T == NULL) {
*T = (TreeNode*)malloc(sizeof(TreeNode));
(*T) -> data = data;
(*T) -> height = 0;
(*T) -> lchild = NULL;
(*T) -> rchild = NULL;
}
else if (data < (*T) -> data) {
avlInsert(&(*T) -> lchild, data);
// 拿到当前节点左右子树的高度
int lHeight = getHeight((*T) -> lchild);
int rHeight = getHeight((*T) -> rchild);
// 判断高度差
if (lHeight - rHeight == 2) {
if (data < (*T) -> lchild -> data) {
// LL 调整
llRotation(*T, T);
}
else {
// LR 调整
rrRotation((*T) -> lchild, &(*T) -> lchild);
llRotation(*T, T);
}
}
}
else if (data > (*T) -> data) {
avlInsert(&(*T) -> rchild, data);
// 拿到当前节点左右子树的高度
int lHeight = getHeight((*T) -> lchild);
int rHeight = getHeight((*T) -> rchild);
// 判断高度差
if (rHeight - lHeight == 2) {
if (data > (*T) -> rchild -> data) {
// RR 调整
rrRotation(*T, T);
}
else {
// RL 调整
llRotation((*T) -> rchild, &(*T) -> rchild);
rrRotation(*T, T);
}
}
}
(*T) -> height = max(getHeight((*T) -> lchild), getHeight((*T) -> rchild)) + 1;
}

void preOrder(TreeNode* T) {
if (T) {
printf("%d ", T -> data);
preOrder(T -> lchild);
preOrder(T -> rchild);
}
}

int main() {
TreeNode* T = NULL;
int nums[5] = {1,8,6,7,10};
for (int i = 0; i < 5; i++) {
avlInsert(&T, nums[i]);
}
preOrder(T);
printf("\n");
}