Skip to content

Commit d747276

Browse files
red black tree
1 parent b53620e commit d747276

File tree

3 files changed

+77
-51
lines changed

3 files changed

+77
-51
lines changed

cormentalgo_test.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ TEST(LinkedList, operloadoutoperator) {
108108
auto temp = linked_list<double>();
109109
temp.push_front(1.5);
110110
temp.push_front(2.5);
111-
temp.print();
111+
// temp.print();
112112
cout.rdbuf(previous);
113113
const auto output = buffer.str();
114114
EXPECT_EQ(string("2.5 1.5 "), output);
@@ -2074,10 +2074,10 @@ TEST_F(non_recursive_binary_search_tree_test, calling_clear_on_empty) {
20742074
TEST_F(non_recursive_binary_search_tree_test, calling_delete_on_root) {
20752075
EXPECT_TRUE(data.empty());
20762076
data.insert(111, 2332);
2077-
data.print();
2077+
// data.print();
20782078
EXPECT_FALSE(data.empty());
20792079
data.remove(111);
2080-
data.print();
2080+
// data.print();
20812081
EXPECT_TRUE(data.empty());
20822082
EXPECT_ANY_THROW(data.minimum());
20832083
EXPECT_ANY_THROW(data.maximum());

red_black.h

Lines changed: 60 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ namespace red_black {
2525
red_black_tree() {
2626
nil = new node<Key, Value>(Key(), Value(), BLACK);
2727
root = nil;
28+
root->parent = root->left = root->right = nil;
2829
sz = 0;
2930
}
3031
// dtor: destroy the red black tree
@@ -57,9 +58,9 @@ namespace red_black {
5758
node<Key, Value>* root;
5859
node<Key, Value>* nil;
5960
size_t sz;
60-
void left_rotate(node<Key, Value>* x);
61-
void right_rotate(node<Key, Value>* x);
62-
void insert_fixup(node<Key, Value>* z);
61+
void left_rotate(node<Key, Value>* &x);
62+
void right_rotate(node<Key, Value>* &x);
63+
void insert_fixup(node<Key, Value>* &z);
6364
void delete_fixup(node<Key, Value>* x);
6465
node<Key, Value>* minimum(node<Key, Value>* x);
6566
node<Key, Value>* maximum(node<Key, Value>* x);
@@ -70,84 +71,90 @@ namespace red_black {
7071

7172
// left_rotate: rotate the tree to the left
7273
template<class Key, class Value>
73-
inline void red_black_tree<Key, Value>::left_rotate(node<Key, Value>* x)
74+
inline void red_black_tree<Key, Value>::left_rotate(node<Key, Value>* &x)
7475
{
75-
auto y = x->right; // set y
76-
x->right = y->left; // turn y's left subtree into x's right subtree
77-
if(y->left != nil)
78-
y->left->parent = x;
79-
y->parent = x->parent; // link x's parent to y
80-
if (x->parent == nil)
81-
root = y;
82-
else if(x == x->parent->left)
83-
x->parent->left = y;
84-
else
85-
x->parent->right = y;
86-
y->left = x; // put x on y's left
87-
x->parent = y;
76+
if(x->right != nil) // performing left_rotate need node at the right of x
77+
{
78+
auto y = x->right; // set y
79+
x->right = y->left; // turn y's left subtree into x's right subtree
80+
if(y->left != nil)
81+
y->left->parent = x;
82+
y->parent = x->parent; // link x's parent to y
83+
if (x->parent == nil)
84+
root = y;
85+
else if((x->parent != nil) && (x == x->parent->left))
86+
x->parent->left = y;
87+
else
88+
x->parent->right = y;
89+
y->left = x; // put x on y's left
90+
x->parent = y;
91+
}
8892
}
8993

9094
// right_rotate: rotate the tree to the right
9195
template<class Key, class Value>
92-
inline void red_black_tree<Key, Value>::right_rotate(node<Key, Value>* x)
96+
inline void red_black_tree<Key, Value>::right_rotate(node<Key, Value>* &x)
9397
{
94-
auto y = x->left; // set y
95-
x->left = y->right; // turn y's right subtree into x's left subtree
96-
if(y->right != nil)
97-
y->right->parent = x;
98-
y->parent = x->parent; // link x's parent to y
99-
if (x->parent == nil)
100-
root = y;
101-
else if(x == x->parent->right)
102-
x->parent->right = y;
103-
else
104-
x->parent->left = y;
105-
y->right = x; // put x on y's right
106-
x->parent = y;
98+
if(x->left != nil){ // performing right rotate need node at the left of x
99+
auto y = x->left; // set y
100+
x->left = y->right; // turn y's right subtree into x's left subtree
101+
if(y->right != nil)
102+
y->right->parent = x;
103+
y->parent = x->parent; // link x's parent to y
104+
if (x->parent == nil)
105+
root = y;
106+
else if((x->parent != nil) && (x == x->parent->right))
107+
x->parent->right = y;
108+
else
109+
x->parent->left = y;
110+
y->right = x; // put x on y's right
111+
x->parent = y;
112+
}
107113
}
108114

109115
// insert_fixup: fix the tree after insertion
110116
template<class Key, class Value>
111-
inline void red_black_tree<Key, Value>::insert_fixup(node<Key, Value>* z)
117+
inline void red_black_tree<Key, Value>::insert_fixup(node<Key, Value>* &z)
112118
{
113119
while (z->parent->color == RED) {
114120
if (z->parent == z->parent->parent->left) {
115121
auto y = z->parent->parent->right;
116-
if (y->color == RED) { // case 1
122+
if (y!=nil && y->color == RED) { // case 1
117123
z->parent->color = BLACK;
118124
y->color = BLACK;
119125
z->parent->parent->color = RED;
120126
z = z->parent->parent;
121127
}
122-
else if (z == z->parent->right) { // case 2
123-
z = z->parent;
124-
left_rotate(z);
125-
}
126-
else { // case 3
127-
z->parent->color = BLACK;
128+
else {
129+
if (z == z->parent->right) { // case 2
130+
z = z->parent;
131+
left_rotate(z);
132+
}
133+
z->parent->color = BLACK; // case 3
128134
z->parent->parent->color = RED;
129135
right_rotate(z->parent->parent);
130136
}
131137
}
132138
else {
133139
auto y = z->parent->parent->left;
134-
if (y->color == RED) { // case 1
140+
if (y!= nil && y->color == RED) { // case 1
135141
z->parent->color = BLACK;
136142
y->color = BLACK;
137143
z->parent->parent->color = RED;
138144
z = z->parent->parent;
139145
}
140-
else if (z == z->parent->left) { // case 2
141-
z = z->parent;
142-
right_rotate(z);
143-
}
144-
else { // case 3
145-
z->parent->color = BLACK;
146+
else{
147+
if (z == z->parent->left) { // case 2
148+
z = z->parent;
149+
right_rotate(z);
150+
}
151+
z->parent->color = BLACK; // case 3
146152
z->parent->parent->color = RED;
147153
left_rotate(z->parent->parent);
148-
}
154+
}
149155
}
150156
}
157+
root->color = BLACK;
151158
}
152159

153160
//minimum: find the minimum node in the tree
@@ -175,8 +182,13 @@ namespace red_black {
175182
y = x;
176183
if (z->key < x->key)
177184
x = x->left;
178-
else
185+
else if(z->key > x->key)
179186
x = x->right;
187+
else{
188+
x->value = value;
189+
--sz;
190+
return;
191+
}
180192
}
181193
z->parent = y;
182194
if(y==nil)

red_black_test.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,18 @@ TEST_F(red_black_test, calling_maximum) {
3838
tree.insert(3, 3);
3939
EXPECT_EQ(tree.maximum().first, 3);
4040
}
41+
TEST_F(red_black_test, calling_random_behavior){
42+
std::set<int> temp;
43+
for(auto i =0; i<20; ++i)
44+
temp.insert(std::rand());
45+
EXPECT_TRUE(tree.empty());
46+
for(auto beg = temp.begin(); beg!= temp.end(); ++beg)
47+
tree.insert(*beg, 0);
48+
EXPECT_FALSE(tree.empty());
49+
EXPECT_EQ(temp.size(), tree.size());
50+
EXPECT_EQ(*temp.begin(), tree.minimum().first);
51+
auto temp_max = temp.end();
52+
--temp_max;
53+
EXPECT_EQ(*temp_max, tree.maximum().first);
54+
}
4155
} // namespace red_black

0 commit comments

Comments
 (0)