Skip to content

Commit ac88b3d

Browse files
committed
RedBlackTree methods till insert()
1 parent b21a67e commit ac88b3d

File tree

4 files changed

+345
-192
lines changed

4 files changed

+345
-192
lines changed

pydatastructs/trees/_backend/cpp/BinarySearchTree.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ static PyObject* BinarySearchTree_insert(BinarySearchTree* self, PyObject* args)
135135
PyObject* key = Py_None;
136136
Py_INCREF(Py_None);
137137
PyObject* data = Py_None;
138-
if (!PyArg_ParseTuple(args, "O|O", &key, &data)) { // ret_parent is optional
138+
if (!PyArg_ParseTuple(args, "O|O", &key, &data)) { // data is optional
139139
return NULL;
140140
}
141141

pydatastructs/trees/_backend/cpp/RedBlackTree.hpp

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <Python.h>
66
#include <structmember.h>
77
#include <cstdlib>
8+
#include <iostream>
89
#include "../../../utils/_backend/cpp/utils.hpp"
910
#include "../../../utils/_backend/cpp/TreeNode.hpp"
1011
#include "../../../linear_data_structures/_backend/cpp/arrays/ArrayForTrees.hpp"
@@ -40,9 +41,155 @@ static PyObject* RedBlackTree___str__(RedBlackTree *self) {
4041
return BinarySearchTree___str__(self->sbbt->bst);
4142
}
4243

44+
static PyObject* RedBlackTree__get_parent(RedBlackTree *self, PyObject* args) {
45+
long node_idx = PyLong_AsLong(PyObject_GetItem(args, PyZero));
46+
BinaryTree* bt = self->sbbt->bst->binary_tree;
47+
PyObject* parent = reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[node_idx])->parent;
48+
return parent;
49+
}
50+
51+
static PyObject* RedBlackTree__get_grand_parent(RedBlackTree *self, PyObject* args) {
52+
PyObject* node_idx = PyObject_GetItem(args, PyZero);
53+
PyObject* parent_idx = RedBlackTree__get_parent(self, Py_BuildValue("(O)", node_idx));
54+
55+
BinaryTree* bt = self->sbbt->bst->binary_tree;
56+
PyObject* grand_parent = reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(parent_idx)])->parent;
57+
return grand_parent;
58+
}
59+
60+
static PyObject* RedBlackTree__get_sibling(RedBlackTree *self, PyObject* args) {
61+
PyObject* node_idx = PyObject_GetItem(args, PyZero);
62+
PyObject* parent_idx = RedBlackTree__get_parent(self, Py_BuildValue("(O)", node_idx));
63+
64+
if (parent_idx == Py_None) {
65+
Py_RETURN_NONE;
66+
}
67+
68+
BinaryTree* bt = self->sbbt->bst->binary_tree;
69+
TreeNode* node = reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(parent_idx)]);
70+
if (node_idx == node->left) {
71+
PyObject* sibling_idx = node->right;
72+
return sibling_idx;
73+
}
74+
else {
75+
PyObject* sibling_idx = node->left;
76+
return sibling_idx;
77+
}
78+
79+
Py_RETURN_NONE;
80+
}
81+
82+
static PyObject* RedBlackTree__get_uncle(RedBlackTree *self, PyObject* args) {
83+
PyObject* node_idx = PyObject_GetItem(args, PyZero);
84+
PyObject* parent_idx = RedBlackTree__get_parent(self, Py_BuildValue("(O)", node_idx));
85+
86+
PyObject* uncle = RedBlackTree__get_sibling(self, Py_BuildValue("(O)", parent_idx));
87+
return uncle;
88+
}
89+
90+
static PyObject* RedBlackTree__is_onleft(RedBlackTree *self, PyObject* args) {
91+
PyObject* node_idx = PyObject_GetItem(args, PyZero);
92+
PyObject* parent_idx = RedBlackTree__get_parent(self, Py_BuildValue("(O)", node_idx));
93+
94+
BinaryTree* bt = self->sbbt->bst->binary_tree;
95+
if (reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(parent_idx)])->left == node_idx) {
96+
Py_RETURN_TRUE;
97+
}
98+
Py_RETURN_FALSE;
99+
}
43100

101+
static PyObject* RedBlackTree__is_onright(RedBlackTree *self, PyObject* args) {
102+
PyObject* node_idx = PyObject_GetItem(args, PyZero);
103+
if (RedBlackTree__is_onleft(self, Py_BuildValue("(O)", node_idx)) == Py_False) {
104+
Py_RETURN_TRUE;
105+
}
106+
Py_RETURN_FALSE;
107+
}
108+
109+
static PyObject* RedBlackTree___fix_insert(RedBlackTree *self, PyObject* args) {
110+
PyObject* node_idx = PyObject_GetItem(args, PyZero);
111+
BinaryTree* bt = self->sbbt->bst->binary_tree;
112+
while (RedBlackTree__get_parent(self, Py_BuildValue("(O)", node_idx)) != Py_None && reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(RedBlackTree__get_parent(self, Py_BuildValue("(O)", node_idx)))])->color == 1 && reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(node_idx)])->color == 1) {
113+
PyObject* parent_idx = RedBlackTree__get_parent(self, Py_BuildValue("(O)", node_idx));
114+
PyObject* grand_parent_idx = RedBlackTree__get_grand_parent(self, Py_BuildValue("(O)", node_idx));
115+
PyObject* uncle_idx = RedBlackTree__get_uncle(self, Py_BuildValue("(O)", node_idx));
116+
117+
if(uncle_idx != Py_None && reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(uncle_idx)])->color == 1) {
118+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(uncle_idx)])->color = 0;
119+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(parent_idx)])->color = 0;
120+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(grand_parent_idx)])->color = 1;
121+
node_idx = grand_parent_idx;
122+
}
123+
else {
124+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(bt->root_idx)])->is_root = false;
125+
if (RedBlackTree__is_onright(self, Py_BuildValue("(O)", parent_idx)) == Py_True) {
126+
if (RedBlackTree__is_onleft(self, Py_BuildValue("(O)", node_idx)) == Py_True) {
127+
SelfBalancingBinaryTree__right_rotate(self->sbbt, Py_BuildValue("(OO)", parent_idx, node_idx));
128+
node_idx = parent_idx;
129+
parent_idx = RedBlackTree__get_parent(self, Py_BuildValue("(O)", node_idx));
130+
}
131+
node_idx = parent_idx;
132+
parent_idx = RedBlackTree__get_parent(self, Py_BuildValue("(O)", node_idx));
133+
SelfBalancingBinaryTree__left_rotate(self->sbbt, Py_BuildValue("(OO)", parent_idx, node_idx));
134+
}
135+
else if (RedBlackTree__is_onleft(self, Py_BuildValue("(O)", parent_idx)) == Py_True) {
136+
if (RedBlackTree__is_onright(self, Py_BuildValue("(O)", node_idx)) == Py_True) {
137+
SelfBalancingBinaryTree__left_rotate(self->sbbt, Py_BuildValue("(OO)", parent_idx, node_idx));
138+
node_idx = parent_idx;
139+
parent_idx = RedBlackTree__get_parent(self, Py_BuildValue("(O)", node_idx));
140+
}
141+
node_idx = parent_idx;
142+
parent_idx = RedBlackTree__get_parent(self, Py_BuildValue("(O)", node_idx));
143+
SelfBalancingBinaryTree__right_rotate(self->sbbt, Py_BuildValue("(OO)", parent_idx, node_idx));
144+
}
145+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(node_idx)])->color = 0;
146+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(parent_idx)])->color = 1;
147+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(bt->root_idx)])->is_root = true;
148+
}
149+
if (reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(node_idx)])->is_root) {
150+
break;
151+
}
152+
}
153+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(bt->root_idx)])->color = 0;
154+
Py_RETURN_NONE;
155+
}
156+
157+
static PyObject* RedBlackTree_insert(RedBlackTree *self, PyObject* args) {
158+
Py_INCREF(Py_None);
159+
PyObject* key = Py_None;
160+
Py_INCREF(Py_None);
161+
PyObject* data = Py_None;
162+
if (!PyArg_ParseTuple(args, "O|O", &key, &data)) { // data is optional
163+
return NULL;
164+
}
165+
SelfBalancingBinaryTree_insert(self->sbbt, Py_BuildValue("(OO)", key, data));
166+
PyObject* node_idx = SelfBalancingBinaryTree_search(self->sbbt, Py_BuildValue("(O)", key), PyDict_New());
167+
168+
BinaryTree* bt = self->sbbt->bst->binary_tree;
169+
TreeNode* node = reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(node_idx)]);
170+
171+
if (PyType_Ready(&TreeNodeType) < 0) { // This has to be present to finalize a type object. This should be called on all type objects to finish their initialization.
172+
return NULL;
173+
}
174+
TreeNode* new_node = reinterpret_cast<TreeNode*>(TreeNode___new__(&TreeNodeType, Py_BuildValue("(OO)", key, data), PyDict_New()));
175+
new_node->parent = node->parent;
176+
new_node->left = node->left;
177+
new_node->right = node->right;
178+
bt->tree->_one_dimensional_array->_data[PyLong_AsLong(node_idx)] = reinterpret_cast<PyObject*>(new_node);
179+
180+
if (node->is_root) {
181+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(node_idx)])->is_root = true;
182+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(node_idx)])->color = 0;
183+
}
184+
else if (reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(node_idx)])->parent)])->color == 1) {
185+
RedBlackTree___fix_insert(self, Py_BuildValue("(O)", node_idx));
186+
}
187+
188+
Py_RETURN_NONE;
189+
}
44190

45191
static struct PyMethodDef RedBlackTree_PyMethodDef[] = {
192+
{"insert", (PyCFunction) RedBlackTree_insert, METH_VARARGS, NULL},
46193
{NULL}
47194
};
48195

0 commit comments

Comments
 (0)