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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
| #include <iostream>
#include <Windows.h>
#include <conio.h>
#define NIIL &sentinel
enum NodeColor{ RED, BLACK };
using namespace std;
struct RBTree
{
int color;
int Data;
RBTree *Parent;
RBTree *Left;
RBTree *Right;
};
struct RBTree sentinel = { BLACK, 0, NULL, NULL, NULL };
struct RBTree *NIL = NIIL;
void Make_RBTree(RBTree **, int);
void Insert_Node(RBTree**, int);
void Insert_Fixup(RBTree**, RBTree*);
void Rotate_Left(RBTree**, RBTree*);
void Rotate_Right(RBTree**, RBTree*);
void Print_RBTree(RBTree*, int);
void Delete_RBTree(RBTree*);
void main()
{
setlocale(0, "");
RBTree *beg = 0;
cout << "Сколько желаете ввести? ";
int n; cin >> n;
Make_RBTree(&beg, n);
Print_RBTree(beg, 5);
Delete_RBTree(beg);
cout << endl;
system("pause");
}
//создание красно-черного дерева
void Make_RBTree(RBTree** Node, int n){
int Data;
while (n > 0) {
cout << "Введите значение ";
cin >> Data;
Insert_Node(Node, Data);
n--;
}
}
//добавление узла в красно-черное дерево
void Insert_Node(RBTree** Node, int Data) {
RBTree **Curent, *Parent, *New_Node;
Curent = Node;
Parent = NIL;
// Поиск местоположения
while (*Curent != NIL) {
Parent = (*Curent);
Curent = Data < (*Curent)->Data ? &((*Curent)->Left) : &((*Curent)->Right);
}
// Создание нового узла
New_Node = new RBTree();
New_Node->Data = Data;
New_Node->Parent = Parent;
New_Node->Left = NIL;
New_Node->Right = NIL;
New_Node->color = RED;
// Вставка элемента в дерево
if (Parent != NIL){
if (Data < Parent->Data) Parent->Left = New_Node;
else Parent->Right = New_Node;
}
else (*Curent) = New_Node;
Insert_Fixup(Node, New_Node);
}
// Поддержка баланса дерева после вставки нового элемента
void Insert_Fixup(RBTree** Node, RBTree* New_Node){
RBTree* Current = New_Node;
// Проверка свойств дерева
while (Current != *(Node) && Current->Parent->color == RED){
// если есть нарушение
if (Current->Parent == Current->Parent->Parent->Left) {
RBTree *ptr = Current->Parent->Parent->Right;
if (ptr->color == RED) {
Current->Parent->color = BLACK;
ptr->color = BLACK;
Current->Parent->Parent->color = RED;
Current = Current->Parent->Parent;
}
else {
if (Current == Current->Parent->Right) {
// сделать Current левым потомком
Current = Current->Parent;
Rotate_Left(Node, Current);
}
// перекрасить и повернуть
Current->Parent->color = BLACK;
Current->Parent->Parent->color = RED;
Rotate_Right(Node, Current->Parent->Parent);
}
}
else {
RBTree *ptr = Current->Parent->Parent->Left;
if (ptr->color == RED) {
Current->Parent->color = BLACK;
ptr->color = BLACK;
Current->Parent->Parent->color = RED;
Current = Current->Parent->Parent;
}
else {
if (Current == Current->Parent->Left) {
Current = Current->Parent;
Rotate_Right(Node, Current);
}
Current->Parent->color = BLACK;
Current->Parent->Parent->color = RED;
Rotate_Left(Node, Current->Parent->Parent);
}
}
}
(*Node)->color = BLACK;
}
//поворот узла Current влево
void Rotate_Left(RBTree** Node, RBTree *Current) {
RBTree *ptr = Current->Right;
Current->Right = ptr->Left;
if (ptr->Left != NIL) ptr->Left->Parent = Current;
if (ptr != NIL) ptr->Parent = Current->Parent;
if (Current->Parent != NIL) {
if (Current == Current->Parent->Left)
Current->Parent->Left = ptr;
else
Current->Parent->Right = ptr;
}
else {
(*Node) = ptr;
}
ptr->Left = Current;
if (Current != NIL) Current->Parent = ptr;
}
//поворот узла Current вправо
void Rotate_Right(RBTree** Node, RBTree *Current) {
RBTree *ptr = Current->Left;
Current->Left = ptr->Right;
if (ptr->Right != NIL) ptr->Right->Parent = Current;
if (ptr != NIL) ptr->Parent = Current->Parent;
if (Current->Parent != NIL) {
if (Current == Current->Parent->Right)
Current->Parent->Right = ptr;
else
Current->Parent->Left = ptr;
}
else {
(*Node) = ptr;
}
ptr->Right = Current;
if (Current != NIL) Current->Parent = ptr;
}
//печать красно-черного дерева
void Print_RBTree(RBTree* Node, int l){
int i;
if (Node != NIL) {
Print_RBTree(Node->Right, l + 1);
for (i = 0; i< l; i++) cout << " ";
//if (Node->color == RED)
//SetConsoleTextAttribute(hStd, FOREGROUND_RED);
printf("%4ld", Node->Data);
//SetConsoleTextAttribute(hStd, atr);
Print_RBTree(Node->Left, l + 1);
}
else cout << endl;
}
//проверка пустоты красно-черного дерева
bool Empty_RBTree(RBTree* Node){
return (Node == NIL ? true : false);
}
//освобождение памяти, выделенной под красно-черное дерево
void Delete_RBTree(RBTree* Node){
if (Node != NIL) {
Delete_RBTree(Node->Left);
Delete_RBTree(Node->Right);
delete(Node);
}
} |