Skip to content

Commit 821ed65

Browse files
committed
Temporary fix for ArrayForTrees, everything working correctly including str() for BinaryTrees
1 parent 9a55742 commit 821ed65

File tree

5 files changed

+83
-67
lines changed

5 files changed

+83
-67
lines changed

pydatastructs/linear_data_structures/_backend/cpp/arrays/ArrayForTrees.hpp

Lines changed: 67 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -11,78 +11,85 @@
1111

1212
typedef struct {
1313
PyObject_HEAD
14-
DynamicOneDimensionalArray* _dynamic_one_dimensional_array;
14+
DynamicOneDimensionalArray* dynamic_one_dimensional_array;
1515
} ArrayForTrees;
1616

1717
static void ArrayForTrees_dealloc(ArrayForTrees *self) {
18-
DynamicOneDimensionalArray_dealloc(self->_dynamic_one_dimensional_array);
18+
DynamicOneDimensionalArray_dealloc(self->dynamic_one_dimensional_array);
1919
Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
2020
}
2121

22-
static PyObject* ArrayForTrees__modify(ArrayForTrees *self) {
23-
if(((double)self->_dynamic_one_dimensional_array->_num/(double)self->_dynamic_one_dimensional_array->_size) < self->_dynamic_one_dimensional_array->_load_factor){
24-
PyObject* new_indices = PyDict_New();
22+
// static PyObject* ArrayForTrees__modify(ArrayForTrees *self) {
23+
// if(((double)self->_dynamic_one_dimensional_array->_num/(double)self->_dynamic_one_dimensional_array->_size) < self->_dynamic_one_dimensional_array->_load_factor){
24+
// PyObject* new_indices = PyDict_New();
2525

26-
// PyObject* arr_new = OneDimensionalArray___new__(&TreeNodeType, reinterpret_cast<PyObject*>(2*self->_num + 1));
27-
// This is how arr_new was made in DynamicOneDimensionalArray__modify() for the previous line :-
28-
long new_size = 2 * self->_dynamic_one_dimensional_array->_num + 1;
29-
PyObject** arr_new = reinterpret_cast<PyObject**>(std::malloc(new_size * sizeof(PyObject*)));
30-
for( int i = 0; i < new_size; i++ ) {
31-
Py_INCREF(Py_None);
32-
arr_new[i] = Py_None;
33-
}
26+
// // PyObject* arr_new = OneDimensionalArray___new__(&TreeNodeType, reinterpret_cast<PyObject*>(2*self->_num + 1));
27+
// // This is how arr_new was made in DynamicOneDimensionalArray__modify() for the previous line :-
28+
// long new_size = 2 * self->_dynamic_one_dimensional_array->_num + 1;
29+
// PyObject** arr_new = reinterpret_cast<PyObject**>(std::malloc(new_size * sizeof(PyObject*)));
30+
// for( int i = 0; i < new_size; i++ ) {
31+
// Py_INCREF(Py_None);
32+
// arr_new[i] = Py_None;
33+
// }
3434

35-
int j=0;
36-
PyObject** _data = self->_dynamic_one_dimensional_array->_one_dimensional_array->_data; // Check this line
37-
for(int i=0; i<=self->_dynamic_one_dimensional_array->_last_pos_filled;i++){
38-
if(_data[i] != Py_None){ // Check this line. Python code: if self[i] is not None:
39-
Py_INCREF(Py_None); // This was put in DynamicOneDimensionalArray line 116
40-
arr_new[j] = _data[i];
41-
PyObject_SetItem(new_indices, reinterpret_cast<PyObject*>(reinterpret_cast<TreeNode*>(_data[i])->key), reinterpret_cast<PyObject*>(j));
42-
j += 1;
43-
}
44-
}
45-
for(int i=0;i<j;i++){
46-
if(reinterpret_cast<TreeNode*>(arr_new[i])->left != Py_None){
47-
reinterpret_cast<TreeNode*>(arr_new[i])->left = PyObject_GetItem(
48-
new_indices,
49-
PyLong_FromLong(
50-
reinterpret_cast<TreeNode*>(_data[PyLong_AsLong(reinterpret_cast<TreeNode*>(arr_new[i])->left)])->key
51-
)
52-
);
53-
}
54-
if(reinterpret_cast<TreeNode*>(arr_new[i])->right != Py_None){
55-
reinterpret_cast<TreeNode*>(arr_new[i])->right = PyObject_GetItem(
56-
new_indices,
57-
PyLong_FromLong(
58-
reinterpret_cast<TreeNode*>(_data[PyLong_AsLong(reinterpret_cast<TreeNode*>(arr_new[i])->right)])->key
59-
)
60-
);
61-
}
62-
if(reinterpret_cast<TreeNode*>(arr_new[i])->parent != Py_None){
63-
reinterpret_cast<TreeNode*>(arr_new[i])->parent = PyObject_GetItem(
64-
new_indices,
65-
PyLong_FromLong(
66-
reinterpret_cast<TreeNode*>(_data[PyLong_AsLong(reinterpret_cast<TreeNode*>(arr_new[i])->parent)])->key
67-
)
68-
);
69-
}
70-
}
71-
self->_dynamic_one_dimensional_array->_last_pos_filled = j - 1;
72-
self->_dynamic_one_dimensional_array->_one_dimensional_array->_data = arr_new;
73-
self->_dynamic_one_dimensional_array->_size = new_size;
74-
self->_dynamic_one_dimensional_array->_size = new_size;
75-
return new_indices;
76-
}
77-
Py_INCREF(Py_None);
78-
return Py_None;
79-
}
35+
// int j=0;
36+
// PyObject** _data = self->_dynamic_one_dimensional_array->_one_dimensional_array->_data; // Check this line
37+
// for(int i=0; i<=self->_dynamic_one_dimensional_array->_last_pos_filled;i++){
38+
// if(_data[i] != Py_None){ // Check this line. Python code: if self[i] is not None:
39+
// Py_INCREF(Py_None); // This was put in DynamicOneDimensionalArray line 116
40+
// arr_new[j] = _data[i];
41+
// PyObject_SetItem(new_indices, reinterpret_cast<PyObject*>(reinterpret_cast<TreeNode*>(_data[i])->key), reinterpret_cast<PyObject*>(j));
42+
// j += 1;
43+
// }
44+
// }
45+
// for(int i=0;i<j;i++){
46+
// if(reinterpret_cast<TreeNode*>(arr_new[i])->left != Py_None){
47+
// reinterpret_cast<TreeNode*>(arr_new[i])->left = PyObject_GetItem(
48+
// new_indices,
49+
// PyLong_FromLong(
50+
// reinterpret_cast<TreeNode*>(_data[PyLong_AsLong(reinterpret_cast<TreeNode*>(arr_new[i])->left)])->key
51+
// )
52+
// );
53+
// }
54+
// if(reinterpret_cast<TreeNode*>(arr_new[i])->right != Py_None){
55+
// reinterpret_cast<TreeNode*>(arr_new[i])->right = PyObject_GetItem(
56+
// new_indices,
57+
// PyLong_FromLong(
58+
// reinterpret_cast<TreeNode*>(_data[PyLong_AsLong(reinterpret_cast<TreeNode*>(arr_new[i])->right)])->key
59+
// )
60+
// );
61+
// }
62+
// if(reinterpret_cast<TreeNode*>(arr_new[i])->parent != Py_None){
63+
// reinterpret_cast<TreeNode*>(arr_new[i])->parent = PyObject_GetItem(
64+
// new_indices,
65+
// PyLong_FromLong(
66+
// reinterpret_cast<TreeNode*>(_data[PyLong_AsLong(reinterpret_cast<TreeNode*>(arr_new[i])->parent)])->key
67+
// )
68+
// );
69+
// }
70+
// }
71+
// self->_dynamic_one_dimensional_array->_last_pos_filled = j - 1;
72+
// self->_dynamic_one_dimensional_array->_one_dimensional_array->_data = arr_new;
73+
// self->_dynamic_one_dimensional_array->_size = new_size;
74+
// self->_dynamic_one_dimensional_array->_size = new_size;
75+
// return new_indices;
76+
// }
77+
// Py_INCREF(Py_None);
78+
// return Py_None;
79+
// }
8080

8181
static struct PyMethodDef ArrayForTrees_PyMethodDef[] = {
82-
{"_modify", (PyCFunction) ArrayForTrees__modify, METH_NOARGS, NULL},
82+
// {"_modify", (PyCFunction) ArrayForTrees__modify, METH_NOARGS, NULL},
8383
{NULL}
8484
};
8585

86+
static struct PyMemberDef ArrayForTrees_PyMemberDef[] = {
87+
{"dynamic_one_dimensional_array", T_OBJECT,
88+
offsetof(ArrayForTrees, dynamic_one_dimensional_array),
89+
0, "doda for ArrayForTrees"},
90+
{NULL},
91+
};
92+
8693
static PyTypeObject ArrayForTreesType = {
8794
/* tp_name */ PyVarObject_HEAD_INIT(NULL, 0) "ArrayForTrees",
8895
/* tp_basicsize */ sizeof(ArrayForTrees),
@@ -111,7 +118,7 @@ static PyTypeObject ArrayForTreesType = {
111118
/* tp_iter */ 0,
112119
/* tp_iternext */ 0,
113120
/* tp_methods */ ArrayForTrees_PyMethodDef,
114-
/* tp_members */ 0,
121+
/* tp_members */ ArrayForTrees_PyMemberDef,
115122
/* tp_getset */ 0,
116123
/* tp_base */ &DynamicOneDimensionalArrayType,
117124
/* tp_dict */ 0,

pydatastructs/linear_data_structures/_backend/cpp/arrays/DynamicOneDimensionalArray.hpp

Lines changed: 1 addition & 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 "DynamicArray.hpp"
910
#include "OneDimensionalArray.hpp"
1011
#include "../../../../utils/_backend/cpp/utils.hpp"

pydatastructs/linear_data_structures/_backend/cpp/arrays/OneDimensionalArray.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#define PY_SSIZE_T_CLEAN
55
#include <Python.h>
66
#include <structmember.h>
7+
// #include <iostream>
78
#include <cstdlib>
89
#include "Array.hpp"
910
#include "../../../../utils/_backend/cpp/utils.hpp"
@@ -109,7 +110,6 @@ static PyObject* OneDimensionalArray___new__(PyTypeObject* type, PyObject *args,
109110
return NULL;
110111
}
111112
}
112-
113113
return reinterpret_cast<PyObject*>(self);
114114
}
115115

pydatastructs/trees/_backend/cpp/BinaryTree.hpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@
99
#include "../../../utils/_backend/cpp/utils.hpp"
1010
#include "../../../utils/_backend/cpp/TreeNode.hpp"
1111
#include "../../../linear_data_structures/_backend/cpp/arrays/ArrayForTrees.hpp"
12+
#include "../../../linear_data_structures/_backend/cpp/arrays/DynamicOneDimensionalArray.hpp"
1213

1314
typedef struct {
1415
PyObject_HEAD
16+
ArrayForTrees* tree;
1517
size_t root_idx;
1618
PyObject* comparator;
17-
PyObject* tree;
1819
size_t size;
1920
bool is_order_statistic;
2021
} BinaryTree;
@@ -59,8 +60,13 @@ static PyObject* BinaryTree___new__(PyTypeObject* type, PyObject *args, PyObject
5960
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.
6061
return NULL;
6162
}
62-
self->tree = PyObject_CallMethod(reinterpret_cast<PyObject*>(&ArrayForTreesType),"__new__", "OOO", &DynamicOneDimensionalArrayType, &TreeNodeType, listroot);
63-
63+
64+
Py_INCREF(Py_None);
65+
ArrayForTrees* p = reinterpret_cast<ArrayForTrees*>(PyObject_CallMethod(reinterpret_cast<PyObject*>(&ArrayForTreesType),"__new__", "OOO", &DynamicOneDimensionalArrayType, &TreeNodeType, listroot));
66+
if( !p ) {
67+
return NULL;
68+
}
69+
self->tree = p;
6470
self->size = 1;
6571
// Python code is modified to ensure comp is never None
6672
if (!PyCallable_Check(comp)) {
@@ -89,10 +95,11 @@ static PyObject* BinaryTree_search(PyTypeObject* type, PyObject *args, PyObject
8995
}
9096

9197
static PyObject* BinaryTree___str__(BinaryTree *self) {
92-
long size = reinterpret_cast<ArrayForTrees*>(self->tree)->_dynamic_one_dimensional_array->_last_pos_filled + 1;
98+
long size = reinterpret_cast<DynamicOneDimensionalArray*>(self->tree)->_last_pos_filled + 1;
9399
PyObject* list = PyList_New(size);
94100
for(int i=0;i<size;i++){
95-
TreeNode* node = reinterpret_cast<TreeNode*>(reinterpret_cast<ArrayForTrees*>(self->tree)->_dynamic_one_dimensional_array->_one_dimensional_array->_data[i]); // check this
101+
OneDimensionalArray* oda = reinterpret_cast<DynamicOneDimensionalArray*>(self->tree)->_one_dimensional_array; // check this
102+
TreeNode* node = reinterpret_cast<TreeNode*>(oda->_data[i]); // check this
96103
if(reinterpret_cast<PyObject*>(node) != Py_None){
97104
PyObject* out = Py_BuildValue("(OllO)", node->left, node->key, node->data, node->right);
98105
Py_INCREF(out);
@@ -117,7 +124,7 @@ static struct PyMethodDef BinaryTree_PyMethodDef[] = {
117124
static PyMemberDef BinaryTree_PyMemberDef[] = {
118125
{"root_idx", T_PYSSIZET, offsetof(BinaryTree, root_idx), READONLY, "Index of the root node"},
119126
{"comparator", T_OBJECT, offsetof(BinaryTree, comparator), 0, "Comparator function"},
120-
{"tree", T_OBJECT, offsetof(BinaryTree, tree), 0, "Tree"},
127+
// {"tree", T_OBJECT, offsetof(BinaryTree, tree), 0, "Tree"},
121128
{"size", T_PYSSIZET, offsetof(BinaryTree, size), READONLY, "Size of the tree"},
122129
{"is_order_statistic", T_BOOL, offsetof(BinaryTree, is_order_statistic), 0, "Whether the tree is ordered statically or not"},
123130
{NULL} /* Sentinel */

pydatastructs/trees/tests/test_binary_trees.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ def test_cpp_BinaryTree():
1414
assert raises(NotImplementedError, b.delete) # Correctly throws NotImplementedError: This is an abstract method
1515
assert raises(NotImplementedError, b.search) # Correctly throws NotImplementedError: This is an abstract method
1616
# print(str(b))
17+
assert str(b) == "[(None, 1, 100, None)]"
1718

1819
test_cpp_BinaryTree()
1920

0 commit comments

Comments
 (0)