Skip to content

Commit 0bc3eb2

Browse files
authored
C++ backend for Self Balancing Binary Tree (#559)
1 parent 557f86b commit 0bc3eb2

File tree

6 files changed

+328
-5
lines changed

6 files changed

+328
-5
lines changed

pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/ArrayStack.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
#define PY_SSIZE_T_CLEAN
55
#include <Python.h>
66
#include <cstdlib>
7-
#include <iostream>
87
#include <structmember.h>
98
#include "../../../../linear_data_structures/_backend/cpp/arrays/DynamicOneDimensionalArray.hpp"
109

pydatastructs/trees/_backend/cpp/BinaryTreeTraversal.hpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "../../../linear_data_structures/_backend/cpp/arrays/ArrayForTrees.hpp"
1414
#include "BinaryTree.hpp"
1515
#include "BinarySearchTree.hpp"
16+
#include "SelfBalancingBinaryTree.hpp"
1617

1718
typedef struct {
1819
PyObject_HEAD
@@ -32,7 +33,13 @@ static PyObject* BinaryTreeTraversal___new__(PyTypeObject* type, PyObject *args,
3233
if (PyType_Ready(&BinarySearchTreeType) < 0) { // This has to be present to finalize a type object. This should be called on all type objects to finish their initialization.
3334
return NULL;
3435
}
35-
if (PyObject_IsInstance(tree, (PyObject *)&BinarySearchTreeType)) {
36+
if (PyType_Ready(&SelfBalancingBinaryTreeType) < 0) { // This has to be present to finalize a type object. This should be called on all type objects to finish their initialization.
37+
return NULL;
38+
}
39+
if (PyObject_IsInstance(tree, (PyObject *)&SelfBalancingBinaryTreeType)) {
40+
self->tree = reinterpret_cast<SelfBalancingBinaryTree*>(tree)->bst->binary_tree;
41+
}
42+
else if (PyObject_IsInstance(tree, (PyObject *)&BinarySearchTreeType)) {
3643
self->tree = reinterpret_cast<BinarySearchTree*>(tree)->binary_tree;
3744
}
3845
else {
Lines changed: 287 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,287 @@
1+
#ifndef TREES_SELFBALANCINGSelfBalancingBinaryTree_HPP
2+
#define TREES_SELFBALANCINGSelfBalancingBinaryTree_HPP
3+
4+
#define PY_SSIZE_T_CLEAN
5+
#include <Python.h>
6+
#include <structmember.h>
7+
#include <cstdlib>
8+
#include "../../../utils/_backend/cpp/utils.hpp"
9+
#include "../../../utils/_backend/cpp/TreeNode.hpp"
10+
#include "../../../linear_data_structures/_backend/cpp/arrays/ArrayForTrees.hpp"
11+
#include "../../../linear_data_structures/_backend/cpp/arrays/DynamicOneDimensionalArray.hpp"
12+
#include "BinarySearchTree.hpp"
13+
14+
typedef struct {
15+
PyObject_HEAD
16+
BinarySearchTree* bst;
17+
ArrayForTrees* tree;
18+
} SelfBalancingBinaryTree;
19+
20+
static void SelfBalancingBinaryTree_dealloc(SelfBalancingBinaryTree *self) {
21+
Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
22+
}
23+
24+
static PyObject* SelfBalancingBinaryTree___new__(PyTypeObject* type, PyObject *args, PyObject *kwds) {
25+
SelfBalancingBinaryTree *self;
26+
self = reinterpret_cast<SelfBalancingBinaryTree*>(type->tp_alloc(type, 0));
27+
28+
if (PyType_Ready(&BinarySearchTreeType) < 0) { // This has to be present to finalize a type object. This should be called on all type objects to finish their initialization.
29+
return NULL;
30+
}
31+
PyObject* p = BinarySearchTree___new__(&BinarySearchTreeType, args, kwds);
32+
self->bst = reinterpret_cast<BinarySearchTree*>(p);
33+
self->tree = reinterpret_cast<BinarySearchTree*>(p)->binary_tree->tree;
34+
35+
return reinterpret_cast<PyObject*>(self);
36+
}
37+
38+
static PyObject* SelfBalancingBinaryTree___str__(SelfBalancingBinaryTree *self) {
39+
return BinarySearchTree___str__(self->bst);
40+
}
41+
42+
static PyObject* SelfBalancingBinaryTree_insert(SelfBalancingBinaryTree* self, PyObject* args) {
43+
return BinarySearchTree_insert(self->bst, args);
44+
}
45+
46+
static PyObject* SelfBalancingBinaryTree_search(SelfBalancingBinaryTree* self, PyObject *args, PyObject *kwds) {
47+
return BinarySearchTree_search(self->bst, args, kwds);
48+
}
49+
50+
static PyObject* SelfBalancingBinaryTree_delete(SelfBalancingBinaryTree* self, PyObject *args, PyObject *kwds) {
51+
return BinarySearchTree_delete(self->bst, args, kwds);
52+
}
53+
54+
static PyObject* SelfBalancingBinaryTree_lower_bound(SelfBalancingBinaryTree* self, PyObject *args, PyObject *kwds) {
55+
return BinarySearchTree_lower_bound(self->bst, args, kwds);
56+
}
57+
58+
static PyObject* SelfBalancingBinaryTree_upper_bound(SelfBalancingBinaryTree* self, PyObject *args, PyObject *kwds) {
59+
return BinarySearchTree_upper_bound(self->bst, args, kwds);
60+
}
61+
62+
static PyObject* SelfBalancingBinaryTree__simple_path(SelfBalancingBinaryTree* self, PyObject *args) {
63+
return BinarySearchTree__simple_path(self->bst, args);
64+
}
65+
66+
static PyObject* SelfBalancingBinaryTree__lca_1(SelfBalancingBinaryTree* self, PyObject *args) {
67+
return BinarySearchTree__simple_path(self->bst, args);
68+
}
69+
70+
static PyObject* SelfBalancingBinaryTree__lca_2(SelfBalancingBinaryTree* self, PyObject *args) {
71+
return BinarySearchTree__simple_path(self->bst, args);
72+
}
73+
74+
static PyObject* SelfBalancingBinaryTree_lowest_common_ancestor(SelfBalancingBinaryTree* self, PyObject *args) {
75+
return BinarySearchTree_lowest_common_ancestor(self->bst, args);
76+
}
77+
78+
static PyObject* SelfBalancingBinaryTree_rank(SelfBalancingBinaryTree* self, PyObject *args) {
79+
return BinarySearchTree_rank(self->bst, args);
80+
}
81+
82+
static PyObject* SelfBalancingBinaryTree_select(SelfBalancingBinaryTree* self, PyObject *args) {
83+
return BinarySearchTree_select(self->bst, args);
84+
}
85+
86+
static PyObject* SelfBalancingBinaryTree__right_rotate(SelfBalancingBinaryTree* self, PyObject *args) {
87+
PyObject* j = PyObject_GetItem(args, PyZero);
88+
PyObject* k = PyObject_GetItem(args, PyOne);
89+
BinaryTree* bt = self->bst->binary_tree;
90+
PyObject* y = reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(k)])->right;
91+
if (y != Py_None) {
92+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(y)])->parent = j;
93+
}
94+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(j)])->left = y;
95+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(k)])->parent = reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(j)])->parent;
96+
if (reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(k)])->parent != Py_None) {
97+
if (reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(k)])->parent)])->left == j) {
98+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(k)])->parent)])->left = k;
99+
}
100+
else {
101+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(k)])->parent)])->right = k;
102+
}
103+
}
104+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(j)])->parent = k;
105+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(k)])->right = j;
106+
PyObject* kp = reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(k)])->parent;
107+
if (kp == Py_None) {
108+
bt->root_idx = k;
109+
}
110+
Py_RETURN_NONE;
111+
}
112+
113+
static PyObject* SelfBalancingBinaryTree__left_rotate(SelfBalancingBinaryTree* self, PyObject *args) {
114+
PyObject* j = PyObject_GetItem(args, PyZero);
115+
PyObject* k = PyObject_GetItem(args, PyOne);
116+
BinaryTree* bt = self->bst->binary_tree;
117+
PyObject* y = reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(k)])->left;
118+
if (y != Py_None) {
119+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(y)])->parent = j;
120+
}
121+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(j)])->right = y;
122+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(k)])->parent = reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(j)])->parent;
123+
if (reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(k)])->parent != Py_None) {
124+
if (reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(k)])->parent)])->left == j) {
125+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(k)])->parent)])->left = k;
126+
}
127+
else {
128+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(k)])->parent)])->right = k;
129+
}
130+
}
131+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(j)])->parent = k;
132+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(k)])->left = j;
133+
PyObject* kp = reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(k)])->parent;
134+
if (kp == Py_None) {
135+
bt->root_idx = k;
136+
}
137+
Py_RETURN_NONE;
138+
}
139+
140+
static PyObject* SelfBalancingBinaryTree__left_right_rotate(SelfBalancingBinaryTree* self, PyObject *args) {
141+
PyObject* j = PyObject_GetItem(args, PyZero);
142+
PyObject* k = PyObject_GetItem(args, PyOne);
143+
BinaryTree* bt = self->bst->binary_tree;
144+
145+
PyObject* i = reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(k)])->right;
146+
PyObject* v = reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(i)])->left;
147+
PyObject* w = reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(i)])->right;
148+
149+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(k)])->right = v;
150+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(j)])->left = w;
151+
152+
if (v != Py_None) {
153+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(v)])->parent = k;
154+
}
155+
if (w != Py_None) {
156+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(w)])->parent = j;
157+
}
158+
159+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(i)])->left = k;
160+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(i)])->right = j;
161+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(i)])->parent = reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(j)])->parent;
162+
163+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(k)])->parent = i;
164+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(j)])->parent = i;
165+
166+
PyObject* ip = reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(i)])->parent;
167+
if (ip != Py_None) {
168+
if (reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(ip)])->left == j) {
169+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(ip)])->left = i;
170+
}
171+
else {
172+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(ip)])->right = i;
173+
}
174+
}
175+
else {
176+
bt->root_idx = i;
177+
}
178+
Py_RETURN_NONE;
179+
}
180+
181+
static PyObject* SelfBalancingBinaryTree__right_left_rotate(SelfBalancingBinaryTree* self, PyObject *args) {
182+
PyObject* j = PyObject_GetItem(args, PyZero);
183+
PyObject* k = PyObject_GetItem(args, PyOne);
184+
BinaryTree* bt = self->bst->binary_tree;
185+
186+
PyObject* i = reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(k)])->left;
187+
PyObject* v = reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(i)])->left;
188+
PyObject* w = reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(i)])->right;
189+
190+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(k)])->left = w;
191+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(j)])->right = v;
192+
193+
if (v != Py_None) {
194+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(v)])->parent = j;
195+
}
196+
if (w != Py_None) {
197+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(w)])->parent = k;
198+
}
199+
200+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(i)])->right = k;
201+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(i)])->left = j;
202+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(i)])->parent = reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(j)])->parent;
203+
204+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(k)])->parent = i;
205+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(j)])->parent = i;
206+
207+
PyObject* ip = reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(i)])->parent;
208+
if (ip != Py_None) {
209+
if (reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(ip)])->left == j) {
210+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(ip)])->left = i;
211+
}
212+
else {
213+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(ip)])->right = i;
214+
}
215+
}
216+
else {
217+
bt->root_idx = i;
218+
}
219+
Py_RETURN_NONE;
220+
}
221+
222+
static struct PyMethodDef SelfBalancingBinaryTree_PyMethodDef[] = {
223+
{"insert", (PyCFunction) SelfBalancingBinaryTree_insert, METH_VARARGS | METH_KEYWORDS, NULL},
224+
{"delete", (PyCFunction) SelfBalancingBinaryTree_delete, METH_VARARGS | METH_KEYWORDS, NULL},
225+
{"search", (PyCFunction) SelfBalancingBinaryTree_search, METH_VARARGS | METH_KEYWORDS, NULL},
226+
{"lower_bound", (PyCFunction) SelfBalancingBinaryTree_lower_bound, METH_VARARGS | METH_KEYWORDS, NULL},
227+
{"upper_bound", (PyCFunction) SelfBalancingBinaryTree_upper_bound, METH_VARARGS | METH_KEYWORDS, NULL},
228+
{"_simple_path", (PyCFunction) SelfBalancingBinaryTree__simple_path, METH_VARARGS, NULL},
229+
{"_lca_1", (PyCFunction) SelfBalancingBinaryTree__lca_1, METH_VARARGS, NULL},
230+
{"_lca_2", (PyCFunction) SelfBalancingBinaryTree__lca_2, METH_VARARGS, NULL},
231+
{"lowest_common_ancestor", (PyCFunction) SelfBalancingBinaryTree_lowest_common_ancestor, METH_VARARGS, NULL},
232+
{"rank", (PyCFunction) SelfBalancingBinaryTree_rank, METH_VARARGS, NULL},
233+
{"select", (PyCFunction) SelfBalancingBinaryTree_select, METH_VARARGS, NULL},
234+
{"_right_rotate", (PyCFunction) SelfBalancingBinaryTree__right_rotate, METH_VARARGS, NULL},
235+
{"_left_rotate", (PyCFunction) SelfBalancingBinaryTree__left_rotate, METH_VARARGS, NULL},
236+
{"_left_right_rotate", (PyCFunction) SelfBalancingBinaryTree__left_right_rotate, METH_VARARGS, NULL},
237+
{"_right_left_rotate", (PyCFunction) SelfBalancingBinaryTree__right_left_rotate, METH_VARARGS, NULL},
238+
{NULL}
239+
};
240+
241+
static PyMemberDef SelfBalancingBinaryTree_PyMemberDef[] = {
242+
{"tree", T_OBJECT_EX, offsetof(SelfBalancingBinaryTree, tree), 0, "tree"},
243+
{NULL} /* Sentinel */
244+
};
245+
246+
247+
static PyTypeObject SelfBalancingBinaryTreeType = {
248+
/* tp_name */ PyVarObject_HEAD_INIT(NULL, 0) "SelfBalancingBinaryTree",
249+
/* tp_basicsize */ sizeof(SelfBalancingBinaryTree),
250+
/* tp_itemsize */ 0,
251+
/* tp_dealloc */ (destructor) SelfBalancingBinaryTree_dealloc,
252+
/* tp_print */ 0,
253+
/* tp_getattr */ 0,
254+
/* tp_setattr */ 0,
255+
/* tp_reserved */ 0,
256+
/* tp_repr */ 0,
257+
/* tp_as_number */ 0,
258+
/* tp_as_sequence */ 0,
259+
/* tp_as_mapping */ 0,
260+
/* tp_hash */ 0,
261+
/* tp_call */ 0,
262+
/* tp_str */ (reprfunc) SelfBalancingBinaryTree___str__,
263+
/* tp_getattro */ 0,
264+
/* tp_setattro */ 0,
265+
/* tp_as_buffer */ 0,
266+
/* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
267+
/* tp_doc */ 0,
268+
/* tp_traverse */ 0,
269+
/* tp_clear */ 0,
270+
/* tp_richcompare */ 0,
271+
/* tp_weaklistoffset */ 0,
272+
/* tp_iter */ 0,
273+
/* tp_iternext */ 0,
274+
/* tp_methods */ SelfBalancingBinaryTree_PyMethodDef,
275+
/* tp_members */ SelfBalancingBinaryTree_PyMemberDef,
276+
/* tp_getset */ 0,
277+
/* tp_base */ &BinarySearchTreeType,
278+
/* tp_dict */ 0,
279+
/* tp_descr_get */ 0,
280+
/* tp_descr_set */ 0,
281+
/* tp_dictoffset */ 0,
282+
/* tp_init */ 0,
283+
/* tp_alloc */ 0,
284+
/* tp_new */ SelfBalancingBinaryTree___new__,
285+
};
286+
287+
#endif

pydatastructs/trees/_backend/cpp/trees.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "BinaryTree.hpp"
33
#include "BinarySearchTree.hpp"
44
#include "BinaryTreeTraversal.hpp"
5+
#include "SelfBalancingBinaryTree.hpp"
56

67
static struct PyModuleDef trees_struct = {
78
PyModuleDef_HEAD_INIT,
@@ -33,5 +34,11 @@ PyMODINIT_FUNC PyInit__trees(void) {
3334
Py_INCREF(&BinaryTreeTraversalType);
3435
PyModule_AddObject(trees, "BinaryTreeTraversal", reinterpret_cast<PyObject*>(&BinaryTreeTraversalType));
3536

37+
if (PyType_Ready(&SelfBalancingBinaryTreeType) < 0) {
38+
return NULL;
39+
}
40+
Py_INCREF(&SelfBalancingBinaryTreeType);
41+
PyModule_AddObject(trees, "SelfBalancingBinaryTree", reinterpret_cast<PyObject*>(&SelfBalancingBinaryTreeType));
42+
3643
return trees;
3744
}

pydatastructs/trees/binary_trees.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,15 @@ class SelfBalancingBinaryTree(BinarySearchTree):
684684
"""
685685
Represents Base class for all rotation based balancing trees like AVL tree, Red Black tree, Splay Tree.
686686
"""
687+
def __new__(cls, key=None, root_data=None, comp=None,
688+
is_order_statistic=False, **kwargs):
689+
backend = kwargs.get('backend', Backend.PYTHON)
690+
if backend == Backend.CPP:
691+
if comp is None:
692+
comp = lambda key1, key2: key1 < key2
693+
return _trees.SelfBalancingBinaryTree(key, root_data, comp, is_order_statistic, **kwargs) # If any argument is not given, then it is passed as None, except for comp
694+
return super().__new__(cls, key, root_data, comp, is_order_statistic, **kwargs)
695+
687696
def _right_rotate(self, j, k):
688697
y = self.tree[k].right
689698
if y is not None:

0 commit comments

Comments
 (0)