-
Notifications
You must be signed in to change notification settings - Fork 0
/
SelfBalancingBinarySearchTree.cpp
166 lines (149 loc) · 4.18 KB
/
SelfBalancingBinarySearchTree.cpp
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
#include "SelfBalancingBinarySearchTree.h"
#include <iostream>
SelfBalancingBinarySearchTree::SelfBalancingBinarySearchTree()
{
}
SelfBalancingBinarySearchTree::~SelfBalancingBinarySearchTree()
{
}
int SelfBalancingBinarySearchTree::IsBalanced(BiTreeNodePointer &imbalanced_node)
{
int is_balanced=true;
imbalanced_node = NULL;
IsBalancedRecursion(GetRoot(), is_balanced, imbalanced_node);
return is_balanced;
}
int SelfBalancingBinarySearchTree::IsBalancedRecursion(BiTreeNodePointer root, int &is_balanced,BiTreeNodePointer &imbalanced_node)
{
if (root == NULL)
{
return 0;
}
else
{
int lchild_depth = IsBalancedRecursion(root->lchild, is_balanced, imbalanced_node);
int rchild_depth = IsBalancedRecursion(root->rchild, is_balanced, imbalanced_node);
if (lchild_depth > rchild_depth + 1 || lchild_depth + 1 < rchild_depth)
{
is_balanced = false;
if (imbalanced_node == NULL)
imbalanced_node = root;
}
if (lchild_depth > rchild_depth)
return lchild_depth + 1;
else
return rchild_depth + 1;
}
}
int SelfBalancingBinarySearchTree::IsBalanced()
{
int is_balanced = true;
BiTreeNodePointer imbalanced_node = NULL;
IsBalancedRecursion(GetRoot(), is_balanced, imbalanced_node);
return is_balanced;
}
int SelfBalancingBinarySearchTree::LeftRotation(BiTreeNodePointer imbalanced_node)
{
if (imbalanced_node == NULL)
return 1;
BiTreeNodePointer original_rchild = imbalanced_node->rchild;
if (original_rchild == NULL)
return 1;
BiTreeNodePointer imbalanced_node_parent = GetParent(imbalanced_node);
if (imbalanced_node_parent==NULL)//有可能这一旋转把根节点给转了,所以需要判断新的根节点
SetRoot(original_rchild);
else//也可能把别的节点给转了,需要改变父节点的指针
{
if (imbalanced_node_parent->lchild == imbalanced_node)
imbalanced_node_parent->lchild = original_rchild;
else
imbalanced_node_parent->rchild = original_rchild;
}
imbalanced_node->rchild = original_rchild->lchild;
original_rchild->lchild = imbalanced_node;
return 0;
}
int SelfBalancingBinarySearchTree::RightRotation(BiTreeNodePointer imbalanced_node)
{//左旋和右旋在实际实现上的区别仅仅在于将所有的左右互换
if (imbalanced_node == NULL)
return 1;
BiTreeNodePointer original_lchild = imbalanced_node->lchild;
if (original_lchild == NULL)
return 1;
BiTreeNodePointer imbalanced_node_parent = GetParent(imbalanced_node);
if (imbalanced_node_parent == NULL)
SetRoot(original_lchild);
else
{
if (imbalanced_node_parent->lchild == imbalanced_node)
imbalanced_node_parent->lchild = original_lchild;
else
imbalanced_node_parent->rchild = original_lchild;
}
imbalanced_node->lchild = original_lchild->rchild;
original_lchild->rchild = imbalanced_node;
return 0;
}
BiTreeNodePointer SelfBalancingBinarySearchTree::InsertNodeWithValue(int value)
{
BiTreeNodePointer new_node= this->BinarySortTree::InsertNodeWithValue(value);
RebalanceOnce();
return new_node;
}
int SelfBalancingBinarySearchTree::RebalanceOnce()
{
BiTreeNodePointer imbalanced_node;
if (!IsBalanced(imbalanced_node))
{
int imba_node_factor = GetBalanceFactor(imbalanced_node);
int imba_node_lchild_factor = GetBalanceFactor(imbalanced_node->lchild);
int imba_node_rchild_factor = GetBalanceFactor(imbalanced_node->rchild);
if (imba_node_factor >= 0 && imba_node_lchild_factor >= 0)//LL
{
RightRotation(imbalanced_node);
return 0;
}
else if (imba_node_factor >= 0 && imba_node_lchild_factor < 0)//LR
{
LeftRotation(imbalanced_node->lchild);
RightRotation(imbalanced_node);
return 0;
}
else if (imba_node_factor < 0 && imba_node_rchild_factor < 0)//RR
{
LeftRotation(imbalanced_node);
return 0;
}
else if (imba_node_factor < 0 && imba_node_rchild_factor >= 0)//RL
{
RightRotation(imbalanced_node->rchild);
LeftRotation(imbalanced_node);
return 0;
}
else
return 1;
}
else
return 1;
}
int SelfBalancingBinarySearchTree::GetBalanceFactor(BiTreeNodePointer node)
{
if (node == NULL)
return 0;
else
{
int lchild_depth = GetDpeth(node->lchild);
int rchild_depth = GetDpeth(node->rchild);
return lchild_depth - rchild_depth;
}
}
int SelfBalancingBinarySearchTree::Balance()
{
if (IsLegalBST())
{
while (!IsBalanced())
RebalanceOnce();
return 1;
}
return 0;
}