Skip to content

Commit f70f0ee

Browse files
committedNov 8, 2020
Red Black Tree Added
1 parent f911c91 commit f70f0ee

File tree

2 files changed

+359
-0
lines changed

2 files changed

+359
-0
lines changed
 

‎Data Structure/34 Red Black Tree.cpp

+355
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,355 @@
1+
2+
/** Which of the favors of your Lord will you deny ? **/
3+
4+
#include<bits/stdc++.h>
5+
using namespace std;
6+
7+
#define LL long long
8+
#define PII pair<int,int>
9+
#define PLL pair<LL,LL>
10+
#define F first
11+
#define S second
12+
13+
#define ALL(x) (x).begin(), (x).end()
14+
#define READ freopen("alu.txt", "r", stdin)
15+
#define WRITE freopen("vorta.txt", "w", stdout)
16+
17+
#ifndef ONLINE_JUDGE
18+
#define DBG(x) cout << __LINE__ << " says: " << #x << " = " << (x) << endl
19+
#else
20+
#define DBG(x)
21+
#define endl "\n"
22+
#endif
23+
24+
#define left 0
25+
#define right 1
26+
27+
struct Node
28+
{
29+
int data,color;
30+
Node *child[2];
31+
32+
Node(int data,int color)
33+
{
34+
this->data = data;
35+
this->color = color;
36+
this->child[left] = NULL;
37+
this->child[right] = NULL;
38+
}
39+
};
40+
41+
#define RED 0
42+
#define BLACK 1
43+
44+
/// Red - 0 , Black - 1
45+
46+
struct RBT
47+
{
48+
Node *root;
49+
50+
RBT()
51+
{
52+
root = NULL;
53+
}
54+
55+
bool red(Node *node)
56+
{
57+
if(node==NULL)
58+
return false;
59+
60+
return node->color == RED;
61+
}
62+
63+
void colorFlip(Node *node)
64+
{
65+
node->color = node->color^1;
66+
node->child[left]->color = node->child[left]->color^1;
67+
node->child[right]->color = node->child[right]->color^1;
68+
}
69+
70+
Node* rotate(Node *node,bool dir)
71+
{
72+
Node *temp = node->child[!dir];
73+
node->child[!dir] = temp->child[dir];
74+
temp->child[dir] = node;
75+
76+
temp->color = node->color;
77+
node->color = RED;
78+
79+
return temp;
80+
}
81+
82+
/// align reds , then rotate
83+
Node* doubleRotate(Node *node,bool dir)
84+
{
85+
node->child[!dir] = rotate(node->child[!dir],!dir);
86+
return rotate(node,dir);
87+
}
88+
89+
void insert(int data)
90+
{
91+
root = __insert(root,data);
92+
root->color = BLACK;
93+
}
94+
95+
Node* INSERT_FIX_UP(Node *node,bool dir)
96+
{
97+
if(red(node->child[dir]))
98+
{
99+
/// case 1 : both child red => any one child has 2 reds in a row (LL LR RR RL) => flip colors
100+
if(red(node->child[!dir]))
101+
{
102+
if(red(node->child[dir]->child[dir]) || red(node->child[dir]->child[!dir]))
103+
{
104+
colorFlip(node);
105+
}
106+
}
107+
else
108+
{
109+
/// case 2 : both child not red
110+
111+
if(red(node->child[dir]->child[dir]))
112+
{
113+
/// any one child has 2 reds in a row (LL RR) => rotate
114+
node = rotate(node,!dir);
115+
}
116+
else if(red(node->child[dir]->child[!dir]))
117+
{
118+
/// any one child has 2 reds in a row (LR RL) => align first , then rotate
119+
node = doubleRotate(node,!dir);
120+
}
121+
}
122+
}
123+
return node;
124+
}
125+
126+
Node* __insert(Node *node,int data)
127+
{
128+
if(node == NULL)
129+
return new Node(data,RED);
130+
131+
bool dir = data > node->data; /// left -> 0 , right -> 1
132+
node->child[dir] = __insert(node->child[dir],data);
133+
134+
return INSERT_FIX_UP(node,dir);
135+
}
136+
137+
bool search(int data)
138+
{
139+
Node* ret = search(root,data);
140+
141+
if(ret==NULL)
142+
return false;
143+
else
144+
return true;
145+
}
146+
147+
Node* search(Node* node,int data)
148+
{
149+
if(node == NULL || node->data==data)
150+
return node;
151+
152+
bool dir = data > node->data;
153+
154+
return search(node->child[dir],data);
155+
}
156+
157+
void preorder()
158+
{
159+
// cout<<"Preorder : ";
160+
preorder(root);
161+
cout<<endl;
162+
}
163+
164+
void preorder(Node *node)
165+
{
166+
if(node == NULL)
167+
return;
168+
169+
cout<<node->data<<":"<<(node->color==RED ? "r":"b");
170+
171+
if(node->child[left] || node->child[right])
172+
cout<<"(";
173+
preorder(node->child[left]);
174+
if(node->child[left] || node->child[right])
175+
cout<<")";
176+
177+
if(node->child[left] || node->child[right])
178+
cout<<"(";
179+
preorder(node->child[right]);
180+
if(node->child[left] || node->child[right])
181+
cout<<")";
182+
}
183+
184+
void delete_(int data)
185+
{
186+
bool ok = false;
187+
root = __delete(root,data,ok);
188+
if(root!=NULL)
189+
root->color = BLACK;
190+
}
191+
192+
Node* __delete(Node *node,int data,bool &ok)
193+
{
194+
if(node == NULL)
195+
{
196+
cout<<"NULL"<<endl;
197+
ok = true;
198+
}
199+
else
200+
{
201+
/// found the delete key
202+
if(node->data == data)
203+
{
204+
/// has one child only
205+
if(node->child[left]==NULL || node->child[right]==NULL)
206+
{
207+
Node* temp = NULL;
208+
if(node->child[left])
209+
temp = node->child[left];
210+
if(node->child[right])
211+
temp = node->child[right];
212+
213+
214+
if(red(node)) /// the node is red => just delete it
215+
{
216+
free(node);
217+
ok = true;
218+
}
219+
else if(red(temp)) /// only child is red => replace with that red child and recolor black . so , black balance restored
220+
{
221+
temp->color = BLACK;
222+
free(node);
223+
ok = true;
224+
}
225+
226+
return temp;
227+
}
228+
else /// has 2 child => replace with inorder predecessor / successor and recurse for that
229+
{
230+
Node *temp = getMax(node->child[left]); /// inorder predecessor : maximum value in the left subtree
231+
232+
node->data = temp->data;
233+
data = temp->data; /// updating with predecessor data as this is the one to delete now
234+
}
235+
}
236+
237+
238+
bool dir = data > node->data;
239+
240+
node->child[dir] = __delete(node->child[dir],data,ok); /// recurse
241+
242+
if(ok==false)
243+
{
244+
node = DELETE_FIX_UP(node,dir,ok);
245+
}
246+
}
247+
248+
return node;
249+
}
250+
251+
Node* DELETE_FIX_UP(Node *node,bool dir, bool &ok)
252+
{
253+
Node *parent = node; /// saving for later red sibling fixing case
254+
Node *sibling = node->child[!dir];
255+
256+
/// Case 1 : Red Sibling => Reduce to deterministic Black Sibling Case
257+
if(red(sibling))
258+
{
259+
node = rotate(node,dir);
260+
sibling = parent->child[!dir];
261+
}
262+
263+
if(sibling != NULL)
264+
{
265+
/// Case 2 Part 1 : Black Sibling with only black children
266+
if(!red(sibling->child[left]) && !red(sibling->child[right]))
267+
{
268+
if(red(parent))
269+
ok = true; /// will color it black and sibling subtree will not have imbalance
270+
271+
parent->color = BLACK; /// if not ok , it will mean DOUBLE BLACK edge
272+
sibling->color = RED;
273+
}
274+
else /// Case 2 Part 2 : Black Sibling with not all black children
275+
{
276+
277+
int initcol_parent = parent->color;
278+
bool isRedSiblingReduction = !(node==parent);
279+
280+
if(red(sibling->child[!dir])) /// RR , LL
281+
{
282+
parent = rotate(parent,dir); /// single rotation
283+
}
284+
else
285+
{
286+
parent = doubleRotate(parent,dir); /// align and rotate
287+
}
288+
289+
parent->color = initcol_parent; /// color will be the same as initial parent
290+
parent->child[left]->color = BLACK;
291+
parent->child[right]->color = BLACK;
292+
293+
if(isRedSiblingReduction)
294+
{
295+
node->child[dir] = parent; /// fixing the child for proper bottom up fixing later
296+
}
297+
else
298+
{
299+
node = parent; /// usual black case
300+
}
301+
302+
ok = true;
303+
}
304+
}
305+
306+
return node;
307+
}
308+
309+
Node* getMax(Node* node)
310+
{
311+
Node* now = node;
312+
313+
while (now && now->child[right] != NULL)
314+
now = now->child[right];
315+
316+
return now;
317+
}
318+
};
319+
320+
int32_t main()
321+
{
322+
// freopen("input7.txt","r",stdin);
323+
// freopen("out7.txt","w",stdout);
324+
325+
RBT r;
326+
327+
string option;
328+
329+
while(cin>>option)
330+
{
331+
int num;
332+
cin>>num;
333+
334+
if(option=="F")
335+
{
336+
bool has = r.search(num);
337+
if(has)
338+
cout<<"True"<<endl;
339+
else
340+
cout<<"False"<<endl;
341+
}
342+
else if(option=="I")
343+
{
344+
r.insert(num);
345+
r.preorder();
346+
}
347+
else if(option=="D")
348+
{
349+
r.delete_(num);
350+
r.preorder();
351+
}
352+
}
353+
354+
return 0;
355+
}

‎README.md

+4
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,10 @@
235235
* [Point Update , Range Query](Data%20Structure/28%20Iterative%20Segment%20Tree%20(Point%20Update%2CRange%20Query).cpp)
236236
*( Possible Variations : Range [ **Multiplication , Min , Max , GCD , LCM , and , or , xor** ] )*
237237
* [Range Update , Point Query](Data%20Structure/29%20Iterative%20Segment%20Tree%20(Range%20Update%2CPoint%20Query).cpp)
238+
239+
* [***Implicit Segment Tree***](/Data%20Structure/33%20ImplicitSegmentTree%20(Point%20Update,Range%20Query).cpp)
240+
241+
* [***Red Black Tree***](Data%20Structure/34%20Red%20Black%20Tree.cpp)
238242

239243
* ***Sparse Table***
240244
* [Range Sum Query](Data%20Structure/31%20Sparse%20Table%20(Range%20Sum%20Query).cpp) : **O(logN)**

0 commit comments

Comments
 (0)
Please sign in to comment.