Skip to content

Commit 103fa8e

Browse files
committed
Updates, removed errors, tests passing
1 parent a8ea072 commit 103fa8e

File tree

2 files changed

+130
-106
lines changed

2 files changed

+130
-106
lines changed

pydatastructs/trees/_backend/cpp/AVLTree.hpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ static PyObject* AVLTree___new__(PyTypeObject* type, PyObject *args, PyObject *k
3131
}
3232
PyObject* p = SelfBalancingBinaryTree___new__(&SelfBalancingBinaryTreeType, args, kwds);
3333
self->sbbt = reinterpret_cast<SelfBalancingBinaryTree*>(p);
34-
self->tree = reinterpret_cast<SelfBalancingBinaryTree*>(p)->bst->binary_tree->tree;
34+
self->tree = self->sbbt->bst->binary_tree->tree;
3535

3636
return reinterpret_cast<PyObject*>(self);
3737
}
@@ -66,9 +66,9 @@ static long AVLTree_right_height(AVLTree* self, PyObject *args) {
6666
}
6767
}
6868

69-
static long AVLTree_balance_factor(AVLTree* self, PyObject *args) {
69+
static PyObject* AVLTree_balance_factor(AVLTree* self, PyObject *args) {
7070
TreeNode* node = reinterpret_cast<TreeNode*>(PyObject_GetItem(args, PyZero));
71-
return AVLTree_left_height(self, Py_BuildValue("(O)", node)) - AVLTree_right_height(self, Py_BuildValue("(O)", node));
71+
return PyLong_FromLong(AVLTree_right_height(self, Py_BuildValue("(O)", node)) - AVLTree_left_height(self, Py_BuildValue("(O)", node)));
7272
}
7373

7474
static PyObject* AVLTree__right_rotate(AVLTree* self, PyObject *args) {
@@ -192,7 +192,7 @@ static PyObject* AVLTree__balance_insertion(AVLTree* self, PyObject *args) {
192192
path.pop();
193193
PyObject* last2last = path.front();
194194
path.pop();
195-
long bf = AVLTree_balance_factor(self, Py_BuildValue("(O)", bt->tree->_one_dimensional_array->_data[PyLong_AsLong(walk)]));
195+
long bf = PyLong_AsLong(AVLTree_balance_factor(self, Py_BuildValue("(O)", bt->tree->_one_dimensional_array->_data[PyLong_AsLong(walk)])));
196196
if (bf != 1 && bf != 0 && bf != -1) {
197197
PyObject* l = reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(walk)])->left;
198198
if (l != Py_None && l == last && reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(l)])->left == last2last) {
@@ -239,6 +239,7 @@ static PyObject* AVLTree_insert(AVLTree* self, PyObject *args) {
239239
static struct PyMethodDef AVLTree_PyMethodDef[] = {
240240
{"search", (PyCFunction) AVLTree_search, METH_VARARGS | METH_KEYWORDS, NULL},
241241
{"insert", (PyCFunction) AVLTree_insert, METH_VARARGS, NULL},
242+
{"balance_factor", (PyCFunction) AVLTree_balance_factor, METH_VARARGS, NULL},
242243
{"_left_right_rotate", (PyCFunction) AVLTree__left_right_rotate, METH_VARARGS, NULL},
243244
{"_right_left_rotate", (PyCFunction) AVLTree__right_left_rotate, METH_VARARGS, NULL},
244245
{"_left_rotate", (PyCFunction) AVLTree__left_rotate, METH_VARARGS, NULL},

pydatastructs/trees/tests/test_binary_trees.py

Lines changed: 125 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from copy import deepcopy
77
from pydatastructs.utils.misc_util import Backend
88
import random
9+
from pydatastructs.utils._backend.cpp import _nodes
910

1011
def _test_BinarySearchTree(backend):
1112
BST = BinarySearchTree
@@ -159,8 +160,8 @@ def test_BinaryTreeTraversal():
159160
def test_cpp_BinaryTreeTraversal():
160161
_test_BinaryTreeTraversal(Backend.CPP)
161162

162-
def test_AVLTree():
163-
a = AVLTree('M', 'M', backend=Backend.CPP)
163+
def _test_AVLTree(backend):
164+
a = AVLTree('M', 'M', backend=backend)
164165
a.insert('N', 'N')
165166
a.insert('O', 'O')
166167
a.insert('L', 'L')
@@ -171,148 +172,162 @@ def test_AVLTree():
171172
a.insert('I', 'I')
172173
a.insert('A', 'A')
173174

174-
trav = BinaryTreeTraversal(a, backend=Backend.CPP)
175+
trav = BinaryTreeTraversal(a, backend=backend)
175176
in_order = trav.depth_first_search(order='in_order')
176177
pre_order = trav.depth_first_search(order='pre_order')
177178
assert [node.key for node in in_order] == ['A', 'H', 'I', 'K', 'L', 'M', 'N', 'O', 'P', 'Q']
178179
assert [node.key for node in pre_order] == ['N', 'I', 'H', 'A', 'L', 'K', 'M', 'P', 'O', 'Q']
179180

180-
# assert [a.balance_factor(n) for n in a.tree if n is not None] == \
181-
# [0, -1, 0, 0, 0, 0, 0, -1, 0, 0]
182-
a1 = AVLTree(1, 1, backend=Backend.CPP)
181+
assert [a.balance_factor(a.tree[i]) for i in range(a.tree.size) if a.tree[i] is not None] == \
182+
[0, -1, 0, 0, 0, 0, 0, -1, 0, 0]
183+
a1 = AVLTree(1, 1, backend=backend)
183184
a1.insert(2, 2)
184185
a1.insert(3, 3)
185186
a1.insert(4, 4)
186187
a1.insert(5, 5)
187188

188-
trav = BinaryTreeTraversal(a1, backend=Backend.CPP)
189+
trav = BinaryTreeTraversal(a1, backend=backend)
189190
in_order = trav.depth_first_search(order='in_order')
190191
pre_order = trav.depth_first_search(order='pre_order')
191192
assert [node.key for node in in_order] == [1, 2, 3, 4, 5]
192193
assert [node.key for node in pre_order] == [2, 1, 4, 3, 5]
193194

194-
a3 = AVLTree(-1, 1, backend=Backend.CPP)
195+
a3 = AVLTree(-1, 1, backend=backend)
195196
a3.insert(-2, 2)
196197
a3.insert(-3, 3)
197198
a3.insert(-4, 4)
198199
a3.insert(-5, 5)
199200

200-
trav = BinaryTreeTraversal(a3, backend=Backend.CPP)
201+
trav = BinaryTreeTraversal(a3, backend=backend)
201202
in_order = trav.depth_first_search(order='in_order')
202203
pre_order = trav.depth_first_search(order='pre_order')
203204
assert [node.key for node in in_order] == [-5, -4, -3, -2, -1]
204205
assert [node.key for node in pre_order] == [-2, -4, -5, -3, -1]
205206

206-
a2 = AVLTree(backend=Backend.CPP)
207+
a2 = AVLTree(backend=backend)
207208
a2.insert(1, 1)
208209
a2.insert(1, 1)
209210

210-
trav = BinaryTreeTraversal(a2, backend=Backend.CPP)
211+
trav = BinaryTreeTraversal(a2, backend=backend)
211212
in_order = trav.depth_first_search(order='in_order')
212213
pre_order = trav.depth_first_search(order='pre_order')
213214
assert [node.key for node in in_order] == [1]
214215
assert [node.key for node in pre_order] == [1]
215216

216-
a3 = AVLTree(backend=Backend.CPP)
217-
a3.tree = ArrayForTrees(TreeNode, 0)
218-
for i in range(7):
219-
a3.tree.append(TreeNode(i, i))
217+
a3 = AVLTree(0,0,backend=backend)
218+
for i in range(1,7):
219+
a3.tree.append(TreeNode(i, i, backend=backend))
220220
a3.tree[0].left = 1
221-
# print(str(a3))
222221
a3.tree[0].right = 6
223222
a3.tree[1].left = 5
224223
a3.tree[1].right = 2
225224
a3.tree[2].left = 3
226225
a3.tree[2].right = 4
227-
# print(str(a3))
228-
# a3._left_right_rotate(0, 1)
226+
a3._left_right_rotate(0, 1)
229227

230-
# trav = BinaryTreeTraversal(a3)
231-
# in_order = trav.depth_first_search(order='in_order')
232-
# pre_order = trav.depth_first_search(order='pre_order')
233-
# assert [node.key for node in in_order] == [5, 1, 3, 2, 4, 0, 6]
234-
# assert [node.key for node in pre_order] == [2, 1, 5, 3, 0, 4, 6]
235-
236-
# a4 = AVLTree()
237-
# a4.tree = ArrayForTrees(TreeNode, 0)
238-
# for i in range(7):
239-
# a4.tree.append(TreeNode(i, i))
240-
# a4.tree[0].left = 1
241-
# a4.tree[0].right = 2
242-
# a4.tree[2].left = 3
243-
# a4.tree[2].right = 4
244-
# a4.tree[3].left = 5
245-
# a4.tree[3].right = 6
246-
# a4._right_left_rotate(0, 2)
247-
248-
# trav = BinaryTreeTraversal(a4)
249-
# in_order = trav.depth_first_search(order='in_order')
250-
# pre_order = trav.depth_first_search(order='pre_order')
251-
# assert [node.key for node in in_order] == [1, 0, 5, 3, 6, 2, 4]
252-
# assert [node.key for node in pre_order] == [3,0,1,5,2,6,4]
253-
254-
# a5 = AVLTree(is_order_statistic=True)
255-
# a5.tree = ArrayForTrees(TreeNode, [
256-
# TreeNode(10, 10),
257-
# TreeNode(5, 5),
258-
# TreeNode(17, 17),
259-
# TreeNode(2, 2),
260-
# TreeNode(9, 9),
261-
# TreeNode(12, 12),
262-
# TreeNode(20, 20),
263-
# TreeNode(3, 3),
264-
# TreeNode(11, 11),
265-
# TreeNode(15, 15),
266-
# TreeNode(18, 18),
267-
# TreeNode(30, 30),
268-
# TreeNode(13, 13),
269-
# TreeNode(33, 33)
270-
# ])
271-
272-
# a5.tree[0].left, a5.tree[0].right, a5.tree[0].parent, a5.tree[0].height = \
273-
# 1, 2, None, 4
274-
# a5.tree[1].left, a5.tree[1].right, a5.tree[1].parent, a5.tree[1].height = \
275-
# 3, 4, 0, 2
276-
# a5.tree[2].left, a5.tree[2].right, a5.tree[2].parent, a5.tree[2].height = \
277-
# 5, 6, 0, 3
278-
# a5.tree[3].left, a5.tree[3].right, a5.tree[3].parent, a5.tree[3].height = \
279-
# None, 7, 1, 1
280-
# a5.tree[4].left, a5.tree[4].right, a5.tree[4].parent, a5.tree[4].height = \
281-
# None, None, 1, 0
282-
# a5.tree[5].left, a5.tree[5].right, a5.tree[5].parent, a5.tree[5].height = \
283-
# 8, 9, 2, 2
284-
# a5.tree[6].left, a5.tree[6].right, a5.tree[6].parent, a5.tree[6].height = \
285-
# 10, 11, 2, 2
286-
# a5.tree[7].left, a5.tree[7].right, a5.tree[7].parent, a5.tree[7].height = \
287-
# None, None, 3, 0
288-
# a5.tree[8].left, a5.tree[8].right, a5.tree[8].parent, a5.tree[8].height = \
289-
# None, None, 5, 0
290-
# a5.tree[9].left, a5.tree[9].right, a5.tree[9].parent, a5.tree[9].height = \
291-
# 12, None, 5, 1
292-
# a5.tree[10].left, a5.tree[10].right, a5.tree[10].parent, a5.tree[10].height = \
293-
# None, None, 6, 0
294-
# a5.tree[11].left, a5.tree[11].right, a5.tree[11].parent, a5.tree[11].height = \
295-
# None, 13, 6, 1
296-
# a5.tree[12].left, a5.tree[12].right, a5.tree[12].parent, a5.tree[12].height = \
297-
# None, None, 9, 0
298-
# a5.tree[13].left, a5.tree[13].right, a5.tree[13].parent, a5.tree[13].height = \
299-
# None, None, 11, 0
228+
trav = BinaryTreeTraversal(a3, backend=backend)
229+
in_order = trav.depth_first_search(order='in_order')
230+
pre_order = trav.depth_first_search(order='pre_order')
231+
assert [node.key for node in in_order] == [5, 1, 3, 2, 4, 0, 6]
232+
assert [node.key for node in pre_order] == [2, 1, 5, 3, 0, 4, 6]
233+
234+
a4 = AVLTree(0,0,backend=backend)
235+
for i in range(1,7):
236+
a4.tree.append(TreeNode(i, i,backend=backend))
237+
a4.tree[0].left = 1
238+
a4.tree[0].right = 2
239+
a4.tree[2].left = 3
240+
a4.tree[2].right = 4
241+
a4.tree[3].left = 5
242+
a4.tree[3].right = 6
243+
a4._right_left_rotate(0, 2)
244+
245+
trav = BinaryTreeTraversal(a4, backend=backend)
246+
in_order = trav.depth_first_search(order='in_order')
247+
pre_order = trav.depth_first_search(order='pre_order')
248+
assert [node.key for node in in_order] == [1, 0, 5, 3, 6, 2, 4]
249+
assert [node.key for node in pre_order] == [3,0,1,5,2,6,4]
250+
251+
a5 = AVLTree(is_order_statistic=True,backend=backend)
252+
if backend==Backend.PYTHON:
253+
a5.tree = ArrayForTrees(TreeNode, [
254+
TreeNode(10, 10),
255+
TreeNode(5, 5),
256+
TreeNode(17, 17),
257+
TreeNode(2, 2),
258+
TreeNode(9, 9),
259+
TreeNode(12, 12),
260+
TreeNode(20, 20),
261+
TreeNode(3, 3),
262+
TreeNode(11, 11),
263+
TreeNode(15, 15),
264+
TreeNode(18, 18),
265+
TreeNode(30, 30),
266+
TreeNode(13, 13),
267+
TreeNode(33, 33)
268+
])
269+
else:
270+
a5.tree = ArrayForTrees(_nodes.TreeNode, [
271+
TreeNode(10, 10,backend=backend),
272+
TreeNode(5, 5,backend=backend),
273+
TreeNode(17, 17,backend=backend),
274+
TreeNode(2, 2,backend=backend),
275+
TreeNode(9, 9,backend=backend),
276+
TreeNode(12, 12,backend=backend),
277+
TreeNode(20, 20,backend=backend),
278+
TreeNode(3, 3,backend=backend),
279+
TreeNode(11, 11,backend=backend),
280+
TreeNode(15, 15,backend=backend),
281+
TreeNode(18, 18,backend=backend),
282+
TreeNode(30, 30,backend=backend),
283+
TreeNode(13, 13,backend=backend),
284+
TreeNode(33, 33,backend=backend)
285+
],backend=backend)
286+
287+
a5.tree[0].left, a5.tree[0].right, a5.tree[0].parent, a5.tree[0].height = \
288+
1, 2, None, 4
289+
a5.tree[1].left, a5.tree[1].right, a5.tree[1].parent, a5.tree[1].height = \
290+
3, 4, 0, 2
291+
a5.tree[2].left, a5.tree[2].right, a5.tree[2].parent, a5.tree[2].height = \
292+
5, 6, 0, 3
293+
a5.tree[3].left, a5.tree[3].right, a5.tree[3].parent, a5.tree[3].height = \
294+
None, 7, 1, 1
295+
a5.tree[4].left, a5.tree[4].right, a5.tree[4].parent, a5.tree[4].height = \
296+
None, None, 1, 0
297+
a5.tree[5].left, a5.tree[5].right, a5.tree[5].parent, a5.tree[5].height = \
298+
8, 9, 2, 2
299+
a5.tree[6].left, a5.tree[6].right, a5.tree[6].parent, a5.tree[6].height = \
300+
10, 11, 2, 2
301+
a5.tree[7].left, a5.tree[7].right, a5.tree[7].parent, a5.tree[7].height = \
302+
None, None, 3, 0
303+
a5.tree[8].left, a5.tree[8].right, a5.tree[8].parent, a5.tree[8].height = \
304+
None, None, 5, 0
305+
a5.tree[9].left, a5.tree[9].right, a5.tree[9].parent, a5.tree[9].height = \
306+
12, None, 5, 1
307+
a5.tree[10].left, a5.tree[10].right, a5.tree[10].parent, a5.tree[10].height = \
308+
None, None, 6, 0
309+
a5.tree[11].left, a5.tree[11].right, a5.tree[11].parent, a5.tree[11].height = \
310+
None, 13, 6, 1
311+
a5.tree[12].left, a5.tree[12].right, a5.tree[12].parent, a5.tree[12].height = \
312+
None, None, 9, 0
313+
a5.tree[13].left, a5.tree[13].right, a5.tree[13].parent, a5.tree[13].height = \
314+
None, None, 11, 0
300315

301316
# # testing order statistics
302-
# a5.tree[0].size = 14
303-
# a5.tree[1].size = 4
304-
# a5.tree[2].size = 9
305-
# a5.tree[3].size = 2
306-
# a5.tree[4].size = 1
307-
# a5.tree[5].size = 4
308-
# a5.tree[6].size = 4
309-
# a5.tree[7].size = 1
310-
# a5.tree[8].size = 1
311-
# a5.tree[9].size = 2
312-
# a5.tree[10].size = 1
313-
# a5.tree[11].size = 2
314-
# a5.tree[12].size = 1
315-
# a5.tree[13].size = 1
317+
a5.tree[0].size = 14
318+
a5.tree[1].size = 4
319+
a5.tree[2].size = 9
320+
a5.tree[3].size = 2
321+
a5.tree[4].size = 1
322+
a5.tree[5].size = 4
323+
a5.tree[6].size = 4
324+
a5.tree[7].size = 1
325+
a5.tree[8].size = 1
326+
a5.tree[9].size = 2
327+
a5.tree[10].size = 1
328+
a5.tree[11].size = 2
329+
a5.tree[12].size = 1
330+
a5.tree[13].size = 1
316331

317332
# assert raises(ValueError, lambda: a5.select(0))
318333
# assert raises(ValueError, lambda: a5.select(15))
@@ -361,7 +376,15 @@ def test_AVLTree():
361376
# test_select_rank([2])
362377
# a5.delete(2)
363378
# test_select_rank([])
379+
380+
def test_AVLTree():
381+
_test_AVLTree(backend=Backend.PYTHON)
382+
383+
def test_cpp_AVLTree():
384+
_test_AVLTree(backend=Backend.CPP)
385+
364386
test_AVLTree()
387+
test_cpp_AVLTree()
365388

366389
def _test_BinaryIndexedTree(backend):
367390

0 commit comments

Comments
 (0)