레드블랙트리 insert구현 / C++

2023. 3. 9. 00:48개인공부/자료구조와 알고리즘

다음 목표는 delete 구현이다.

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
    #pragma once
 
    enum class COLOR
    {
        BLACK,
        RED,
    };
 
    struct Node
    {
        int iKey;
        COLOR Color;
        Node* Parent;
        Node* LeftChild;
        Node* RightChild;
 
        Node();
        ~Node();
    };
 
    class RedBlackTree
    {
    private:
        Node* Root;
        Node* Leaf;
    public:
        void insert(int _key);
        Node* find(int _key);
 
    private:
        void RightRotation(Node* x);
        void LeftRotation(Node* x);
        void InsertFix(Node* x);
        bool IsRightChild(Node* x);
        bool IsLeftChild(Node* x);
 
    private:
        Node* grandparent(Node* n);
        Node* uncle(Node* n);
 
    public:
        RedBlackTree();
        ~RedBlackTree();
 
    };
 
 
cs
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
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
 
#include "RedBlackTree.h"
 
Node::Node()
    :iKey(0)
    , Color(COLOR::RED) // 처음 노드는 빨간색으로 시작
    , Parent(nullptr)
    , LeftChild(nullptr)
    , RightChild(nullptr)
{
}
 
Node::~Node()
{
}
 
void RedBlackTree::insert(int _key)
{
    Node* node = new Node;
    node->Color = COLOR::RED;
    node->iKey = _key;
    node->LeftChild = Leaf;
    node->RightChild = Leaf;
 
    // 처음으로 노드가 들어옴
    if (Root == nullptr)
    {
        Root = node;
        node->Color = COLOR::BLACK; // #1 루트노드는 검정색이다
        return;
    }
 
    Node* iter = Root;
    while (true)
    {
        if (iter->iKey > _key)
        {
            if (iter->LeftChild == Leaf) // 왼쪽자식이 리프
            {
                iter->LeftChild = node;
                node->Parent = iter;
                break;
            }
            else
                iter = iter->LeftChild;
        }
        else
        {
            if (iter->RightChild == Leaf)
            {
                iter->RightChild = node;
                node->Parent = iter;
                break;
            }
            else
                iter = iter->RightChild;
        }
    }
 
    InsertFix(node);
 
    return;
}
 
Node* RedBlackTree::find(int _key)
{
    Node* iter = Root;
    while (iter != Leaf)
    {
        if (iter->iKey == _key)
            return iter;
        else if (iter->iKey > _key)
            iter = iter->LeftChild;
        else
            iter = iter->RightChild;
    }
    return nullptr;
}
 
void RedBlackTree::RightRotation(Node* x)
{
    Node* g = grandparent(x);
    Node* p = x->Parent;
 
    // 오른쪽 노드가 존재하면
    if (x->RightChild != Leaf)
        x->RightChild->Parent = p;
    p->LeftChild = x->RightChild;
 
    x->RightChild = p; 
    p->Parent = x;
    x->Parent = g;
 
    if (g == nullptr)  // p 가 루트노드이다 
    {
        Root = x;
        x->Color = COLOR::BLACK;
    }
    else 
    {
        if (g->LeftChild == p)
            g->LeftChild = x;
        else
            g->RightChild = x;
    }
 
}
 
void RedBlackTree::LeftRotation(Node* x)
{
    Node* g = grandparent(x);
    Node* p = x->Parent;
 
    // 오른쪽 노드가 존재하면
    if (x->LeftChild != Leaf)
        x->LeftChild->Parent = p;
    p->RightChild = x->LeftChild;
 
    x->LeftChild = p;
    p->Parent = x;
    x->Parent = g;
 
    if (g == nullptr)  // p 가 루트노드이다 
    {
        Root = x;
        x->Color = COLOR::BLACK;
    }
    else
    {
        if (g->LeftChild == p)
            g->LeftChild = x;
        else
            g->RightChild = x;
    }
 
}
 
void RedBlackTree::InsertFix(Node* x)
{
    // Root 노드 
    if (x->Parent == nullptr)
    {
        x->Color = COLOR::BLACK;
        return;
    }
    // 규칙만족
    if (x->Color != x->Parent->Color)
        return;
 
    Node* u = uncle(x);
    // case1:삼촌 노드가 RED인 경우
    if (u->Color == COLOR::RED)
    {
        u->Color = COLOR::BLACK;
        x->Parent->Color = COLOR::BLACK;
        x->Parent->Parent->Color = COLOR::RED;
        x = x->Parent->Parent;
        InsertFix(x);
        return;
    }
    // case2:새로 삽입한 노드가 부모노드의 오른쪽 자식인 경우
    if (IsRightChild(x->Parent) && IsLeftChild(x))
    {
        RightRotation(x);
        x = x->RightChild;
    }
    else if (IsLeftChild(x->Parent) && IsRightChild(x))
    {
        LeftRotation(x);
        x = x->LeftChild;
    }
    // case3:새로 삽입한 노드가 부모노드의 왼쪽 자식인 경우
    if (uncle(x) && uncle(x)->Color == COLOR::BLACK)
    {
        x->Parent->Color = COLOR::BLACK;
        grandparent(x)->Color = COLOR::RED;
        if (IsLeftChild(x->Parent))
            RightRotation(x->Parent);
        else
            LeftRotation(x->Parent);
    }
}
 
bool RedBlackTree::IsLeftChild(Node* x)
{
    Node* p = x->Parent;
    if (p == nullptr)
        return false;
 
    if (p->LeftChild == x)
        return true;
 
    return false;
}
 
bool RedBlackTree::IsRightChild(Node* x)
{
    Node* p = x->Parent;
    if (p == nullptr)
        return false;
 
    if (p->RightChild == x)
        return true;
 
    return false;
}
 
Node* RedBlackTree::grandparent(Node* n)
{
    if (n->Parent->Parent == nullptr)
        return nullptr;
 
    return n->Parent->Parent;
}
 
Node* RedBlackTree::uncle(Node* n)
{
    Node* node = grandparent(n);
    if ( node == nullptr)
        return nullptr;
    if (node->LeftChild == n->Parent)
        return node->RightChild;
    else
        return node->LeftChild;
}
 
RedBlackTree::RedBlackTree()
    :Root(nullptr)
{
    Leaf = new Node;
    Leaf->Color = COLOR::BLACK;
}
 
RedBlackTree::~RedBlackTree()
{
    delete Leaf;
}
 
cs

'개인공부 > 자료구조와 알고리즘' 카테고리의 다른 글

레드블랙트리 - 삭제  (0) 2023.03.10
레드블랙트리 증감연산자 / C++  (0) 2023.03.10
레드블랙트리 (자가균형 이진탐색트리)  (0) 2023.03.08
STL 정렬 sort 함수  (0) 2023.02.09
Queue(큐)  (0) 2023.01.25