Skip to content

Commit 83c74dc

Browse files
committed
added postorder traversal in C++ backend and its tests
1 parent 36bc778 commit 83c74dc

File tree

2 files changed

+47
-3
lines changed

2 files changed

+47
-3
lines changed

pydatastructs/trees/_backend/cpp/BinaryTreeTraversal.hpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,46 @@ static PyObject* BinaryTreeTraversal__in_order(BinaryTreeTraversal* self, PyObje
8787
return visit;
8888
}
8989

90+
static PyObject* BinaryTreeTraversal__post_order(BinaryTreeTraversal* self, PyObject *args){
91+
PyObject* node = PyObject_GetItem(args, PyZero);
92+
PyObject* visit = PyList_New(0);
93+
ArrayForTrees* tree = self->tree->tree;
94+
long size = self->tree->size;
95+
std::stack<PyObject*> s;
96+
s.push(node);
97+
PyObject* last = PyList_New(size);
98+
for (int i=0;i<size;i++) {
99+
PyList_SetItem(last, i, PyZero);
100+
}
101+
102+
while (!s.empty()) {
103+
PyObject* node = s.top();
104+
PyObject* l = reinterpret_cast<TreeNode*>(tree->_one_dimensional_array->_data[PyLong_AsLong(node)])->left;
105+
PyObject* r = reinterpret_cast<TreeNode*>(tree->_one_dimensional_array->_data[PyLong_AsLong(node)])->right;
106+
bool cl = false, cr = false;
107+
if (l == Py_None || PyList_GetItem(last, PyLong_AsLong(l)) == PyOne) {
108+
cl = true;
109+
}
110+
if (r == Py_None || PyList_GetItem(last, PyLong_AsLong(r)) == PyOne) {
111+
cr = true;
112+
}
113+
if (cl && cr) {
114+
s.pop();
115+
TreeNode* curr_node = reinterpret_cast<TreeNode*>(tree->_one_dimensional_array->_data[PyLong_AsLong(node)]);
116+
PyList_Append(visit, reinterpret_cast<PyObject*>(curr_node));
117+
PyList_SetItem(last, PyLong_AsLong(node), PyOne);
118+
continue;
119+
}
120+
if (!cr) {
121+
s.push(r);
122+
}
123+
if (!cl) {
124+
s.push(l);
125+
}
126+
}
127+
return visit;
128+
}
129+
90130
static PyObject* BinaryTreeTraversal__out_order(BinaryTreeTraversal* self, PyObject *args){
91131
PyObject* node = PyObject_GetItem(args, PyZero);
92132
PyObject* visit = BinaryTreeTraversal__in_order(self, Py_BuildValue("(O)", node));
@@ -114,6 +154,9 @@ static PyObject* BinaryTreeTraversal_depth_first_search(BinaryTreeTraversal* sel
114154
else if (PyUnicode_Compare(order, PyUnicode_FromString("out_order")) == 0) {
115155
return BinaryTreeTraversal__out_order(self, Py_BuildValue("(O)", node));
116156
}
157+
else if (PyUnicode_Compare(order, PyUnicode_FromString("post_order")) == 0) {
158+
return BinaryTreeTraversal__post_order(self, Py_BuildValue("(O)", node));
159+
}
117160
else {
118161
PyErr_SetString(PyExc_NotImplementedError, "This traversal is not implemented yet or does not exist. Supported traversals: \"pre_order\", \"in_order\", \"out_order\"");
119162
return NULL;
@@ -124,6 +167,7 @@ static struct PyMethodDef BinaryTreeTraversal_PyMethodDef[] = {
124167
{"_pre_order", (PyCFunction) BinaryTreeTraversal__pre_order, METH_VARARGS, NULL},
125168
{"_in_order", (PyCFunction) BinaryTreeTraversal__in_order, METH_VARARGS, NULL},
126169
{"_out_order", (PyCFunction) BinaryTreeTraversal__out_order, METH_VARARGS, NULL},
170+
{"_post_order", (PyCFunction) BinaryTreeTraversal__post_order, METH_VARARGS, NULL},
127171
{"depth_first_search", (PyCFunction) BinaryTreeTraversal_depth_first_search, METH_VARARGS | METH_KEYWORDS, NULL},
128172
{NULL}
129173
};

pydatastructs/trees/tests/test_binary_trees.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,10 @@ def _test_BinaryTreeTraversal(backend):
137137
out = trav.depth_first_search(order='out_order')
138138
assert [node.key for node in out] == ['I', 'H', 'G', 'F', 'E', 'D', 'C', 'B', 'A']
139139

140-
if(backend==Backend.PYTHON): # These are yet to be implemented in the C++ backend
141-
post = trav.depth_first_search(order='post_order')
142-
assert [node.key for node in post] == ['A', 'C', 'E', 'D', 'B', 'H', 'I', 'G', 'F']
140+
post = trav.depth_first_search(order='post_order')
141+
assert [node.key for node in post] == ['A', 'C', 'E', 'D', 'B', 'H', 'I', 'G', 'F']
143142

143+
if(backend==Backend.PYTHON): # These are yet to be implemented in the C++ backend
144144
bfs = trav.breadth_first_search()
145145
assert [node.key for node in bfs] == ['F', 'B', 'G', 'A', 'D', 'I', 'C', 'E', 'H']
146146

0 commit comments

Comments
 (0)