Skip to content

Commit 8c5f1e7

Browse files
committed
SelfBalancignBinaryTree _right_rotate() added
1 parent 557f86b commit 8c5f1e7

File tree

4 files changed

+195
-0
lines changed

4 files changed

+195
-0
lines changed

pydatastructs/trees/_backend/cpp/BinaryTreeTraversal.hpp

Lines changed: 7 additions & 0 deletions
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,6 +33,12 @@ 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
}
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+
else if (PyObject_IsInstance(tree, (PyObject *)&SelfBalancingBinaryTreeType)) {
40+
self->tree = reinterpret_cast<SelfBalancingBinaryTree*>(tree)->bst->binary_tree;
41+
}
3542
if (PyObject_IsInstance(tree, (PyObject *)&BinarySearchTreeType)) {
3643
self->tree = reinterpret_cast<BinarySearchTree*>(tree)->binary_tree;
3744
}
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
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+
} SelfBalancingBinaryTree;
18+
19+
static void SelfBalancingBinaryTree_dealloc(SelfBalancingBinaryTree *self) {
20+
Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
21+
}
22+
23+
static PyObject* SelfBalancingBinaryTree___new__(PyTypeObject* type, PyObject *args, PyObject *kwds) {
24+
SelfBalancingBinaryTree *self;
25+
self = reinterpret_cast<SelfBalancingBinaryTree*>(type->tp_alloc(type, 0));
26+
27+
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.
28+
return NULL;
29+
}
30+
PyObject* p = BinarySearchTree___new__(&BinarySearchTreeType, args, kwds);
31+
self->bst = reinterpret_cast<BinarySearchTree*>(p);
32+
33+
return reinterpret_cast<PyObject*>(self);
34+
}
35+
36+
static PyObject* SelfBalancingBinaryTree___str__(SelfBalancingBinaryTree *self) {
37+
return BinarySearchTree___str__(self->bst);
38+
}
39+
40+
static PyObject* SelfBalancingBinaryTree_insert(SelfBalancingBinaryTree* self, PyObject* args) {
41+
return BinarySearchTree_insert(self->bst, args);
42+
}
43+
44+
static PyObject* SelfBalancingBinaryTree_search(SelfBalancingBinaryTree* self, PyObject *args, PyObject *kwds) {
45+
return BinarySearchTree_search(self->bst, args, kwds);
46+
}
47+
48+
static PyObject* SelfBalancingBinaryTree_delete(SelfBalancingBinaryTree* self, PyObject *args, PyObject *kwds) {
49+
return BinarySearchTree_delete(self->bst, args, kwds);
50+
}
51+
52+
static PyObject* SelfBalancingBinaryTree_lower_bound(SelfBalancingBinaryTree* self, PyObject *args, PyObject *kwds) {
53+
return BinarySearchTree_lower_bound(self->bst, args, kwds);
54+
}
55+
56+
static PyObject* SelfBalancingBinaryTree_upper_bound(SelfBalancingBinaryTree* self, PyObject *args, PyObject *kwds) {
57+
return BinarySearchTree_upper_bound(self->bst, args, kwds);
58+
}
59+
60+
static PyObject* SelfBalancingBinaryTree__simple_path(SelfBalancingBinaryTree* self, PyObject *args) {
61+
return BinarySearchTree__simple_path(self->bst, args);
62+
}
63+
64+
static PyObject* SelfBalancingBinaryTree__lca_1(SelfBalancingBinaryTree* self, PyObject *args) {
65+
return BinarySearchTree__simple_path(self->bst, args);
66+
}
67+
68+
static PyObject* SelfBalancingBinaryTree__lca_2(SelfBalancingBinaryTree* self, PyObject *args) {
69+
return BinarySearchTree__simple_path(self->bst, args);
70+
}
71+
72+
static PyObject* SelfBalancingBinaryTree_lowest_common_ancestor(SelfBalancingBinaryTree* self, PyObject *args) {
73+
return BinarySearchTree_lowest_common_ancestor(self->bst, args);
74+
}
75+
76+
static PyObject* SelfBalancingBinaryTree_rank(SelfBalancingBinaryTree* self, PyObject *args) {
77+
return BinarySearchTree_rank(self->bst, args);
78+
}
79+
80+
static PyObject* SelfBalancingBinaryTree_select(SelfBalancingBinaryTree* self, PyObject *args) {
81+
return BinarySearchTree_select(self->bst, args);
82+
}
83+
84+
static PyObject* SelfBalancingBinaryTree__right_rotate(SelfBalancingBinaryTree* self, PyObject *args) {
85+
PyObject* j = PyObject_GetItem(args, PyZero);
86+
PyObject* k = PyObject_GetItem(args, PyOne);
87+
BinaryTree* bt = self->bst->binary_tree;
88+
PyObject* y = reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(k)])->right;
89+
if (y!=Py_None) {
90+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(y)])->parent = j;
91+
}
92+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(j)])->left = y;
93+
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;
94+
if (reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(k)])->parent != Py_None) {
95+
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) {
96+
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;
97+
}
98+
else {
99+
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;
100+
}
101+
}
102+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(j)])->parent = k;
103+
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(k)])->right = j;
104+
PyObject* kp = reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(k)])->parent;
105+
if (kp == Py_None) {
106+
bt->root_idx = k;
107+
}
108+
Py_RETURN_NONE;
109+
}
110+
111+
static struct PyMethodDef SelfBalancingBinaryTree_PyMethodDef[] = {
112+
{"insert", (PyCFunction) SelfBalancingBinaryTree_insert, METH_VARARGS | METH_KEYWORDS, NULL},
113+
{"delete", (PyCFunction) SelfBalancingBinaryTree_delete, METH_VARARGS | METH_KEYWORDS, NULL},
114+
{"search", (PyCFunction) SelfBalancingBinaryTree_search, METH_VARARGS | METH_KEYWORDS, NULL},
115+
{"lower_bound", (PyCFunction) SelfBalancingBinaryTree_lower_bound, METH_VARARGS | METH_KEYWORDS, NULL},
116+
{"upper_bound", (PyCFunction) SelfBalancingBinaryTree_upper_bound, METH_VARARGS | METH_KEYWORDS, NULL},
117+
{"_simple_path", (PyCFunction) SelfBalancingBinaryTree__simple_path, METH_VARARGS, NULL},
118+
{"_lca_1", (PyCFunction) SelfBalancingBinaryTree__lca_1, METH_VARARGS, NULL},
119+
{"_lca_2", (PyCFunction) SelfBalancingBinaryTree__lca_2, METH_VARARGS, NULL},
120+
{"lowest_common_ancestor", (PyCFunction) SelfBalancingBinaryTree_lowest_common_ancestor, METH_VARARGS, NULL},
121+
{"rank", (PyCFunction) SelfBalancingBinaryTree_rank, METH_VARARGS, NULL},
122+
{"select", (PyCFunction) SelfBalancingBinaryTree_select, METH_VARARGS, NULL},
123+
{"_right_rotate", (PyCFunction) SelfBalancingBinaryTree__right_rotate, METH_VARARGS, NULL},
124+
{NULL}
125+
};
126+
127+
static PyMemberDef SelfBalancingBinaryTree_PyMemberDef[] = {
128+
{NULL} /* Sentinel */
129+
};
130+
131+
132+
static PyTypeObject SelfBalancingBinaryTreeType = {
133+
/* tp_name */ PyVarObject_HEAD_INIT(NULL, 0) "SelfBalancingBinaryTree",
134+
/* tp_basicsize */ sizeof(SelfBalancingBinaryTree),
135+
/* tp_itemsize */ 0,
136+
/* tp_dealloc */ (destructor) SelfBalancingBinaryTree_dealloc,
137+
/* tp_print */ 0,
138+
/* tp_getattr */ 0,
139+
/* tp_setattr */ 0,
140+
/* tp_reserved */ 0,
141+
/* tp_repr */ 0,
142+
/* tp_as_number */ 0,
143+
/* tp_as_sequence */ 0,
144+
/* tp_as_mapping */ 0,
145+
/* tp_hash */ 0,
146+
/* tp_call */ 0,
147+
/* tp_str */ (reprfunc) SelfBalancingBinaryTree___str__,
148+
/* tp_getattro */ 0,
149+
/* tp_setattro */ 0,
150+
/* tp_as_buffer */ 0,
151+
/* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
152+
/* tp_doc */ 0,
153+
/* tp_traverse */ 0,
154+
/* tp_clear */ 0,
155+
/* tp_richcompare */ 0,
156+
/* tp_weaklistoffset */ 0,
157+
/* tp_iter */ 0,
158+
/* tp_iternext */ 0,
159+
/* tp_methods */ SelfBalancingBinaryTree_PyMethodDef,
160+
/* tp_members */ SelfBalancingBinaryTree_PyMemberDef,
161+
/* tp_getset */ 0,
162+
/* tp_base */ &BinarySearchTreeType,
163+
/* tp_dict */ 0,
164+
/* tp_descr_get */ 0,
165+
/* tp_descr_set */ 0,
166+
/* tp_dictoffset */ 0,
167+
/* tp_init */ 0,
168+
/* tp_alloc */ 0,
169+
/* tp_new */ SelfBalancingBinaryTree___new__,
170+
};
171+
172+
#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)