Skip to content

Commit

Permalink
Splay Trees split()
Browse files Browse the repository at this point in the history
  • Loading branch information
Kishan-Ved committed Jun 24, 2024
1 parent 202948a commit ca0c042
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 14 deletions.
71 changes: 71 additions & 0 deletions pydatastructs/trees/_backend/cpp/SplayTree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "../../../utils/_backend/cpp/TreeNode.hpp"
#include "../../../linear_data_structures/_backend/cpp/arrays/ArrayForTrees.hpp"
#include "../../../linear_data_structures/_backend/cpp/arrays/DynamicOneDimensionalArray.hpp"
#include "BinaryTreeTraversal.hpp"
#include "BinarySearchTree.hpp"
#include "SelfBalancingBinaryTree.hpp"

Expand Down Expand Up @@ -216,14 +217,82 @@ static PyObject* SplayTree_join(SplayTree *self, PyObject* args) {
Py_RETURN_NONE;
}

static PyObject* SplayTree__pre_order(SplayTree* self, PyObject *args) {
long node = PyLong_AsLong(PyObject_GetItem(args, PyZero));
PyObject* visit = PyList_New(0);
ArrayForTrees* tree = self->sbbt->bst->binary_tree->tree;
long size = self->sbbt->bst->binary_tree->size;
std::stack<long> s;
s.push(node);

while (!s.empty()) {
node = s.top();
s.pop();
TreeNode* curr_node = reinterpret_cast<TreeNode*>(tree->_one_dimensional_array->_data[node]);
PyList_Append(visit, reinterpret_cast<PyObject*>(curr_node));
if (curr_node->right != Py_None) {
s.push(PyLong_AsLong(curr_node->right));
}
if (curr_node->left != Py_None) {
s.push(PyLong_AsLong(curr_node->left));
}
}
return visit;
}

static PyObject* SplayTree_split(SplayTree *self, PyObject* args) {
PyObject* x = PyObject_GetItem(args, PyZero);
BinaryTree* bt = self->sbbt->bst->binary_tree;

PyObject* kwd_parent = PyDict_New();
PyDict_SetItemString(kwd_parent, "parent", PyLong_FromLong(1));
PyObject* tup = SelfBalancingBinaryTree_search(self->sbbt, Py_BuildValue("(O)", x), kwd_parent);
PyObject* e = PyTuple_GetItem(tup, 0);
PyObject* p = PyTuple_GetItem(tup, 1);
if (e == Py_None) {
Py_RETURN_NONE;
}
SplayTree_splay(self, Py_BuildValue("(OO)", e, p));

Py_INCREF(Py_None);
Py_INCREF(Py_None);
// SplayTree* other = reinterpret_cast<SplayTree*>(SplayTree___new__(self->type, Py_BuildValue("(OO)", Py_None, Py_None), PyDict_New()));
SplayTree* other = reinterpret_cast<SplayTree*>(PyObject_GetItem(args, PyOne));

if (reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(bt->root_idx)])->right != Py_None) {
// if (PyType_Ready(&BinaryTreeTraversalType) < 0) { // This has to be present to finalize a type object. This should be called on all type objects to finish their initialization.
// return NULL;
// }
// BinaryTreeTraversal* traverse = reinterpret_cast<BinaryTreeTraversal*>(BinaryTreeTraversal___new__(&BinaryTreeTraversalType, Py_BuildValue("(O)", self), PyDict_New()));
// PyObject* kwd_dict = PyDict_New();
// PyDict_SetItemString(kwd_dict, "node", reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(bt->root_idx)])->right);
// PyDict_SetItemString(kwd_dict, "order", PyUnicode_FromString("pre_order"));
// PyObject* elements = BinaryTreeTraversal_depth_first_search(traverse, Py_BuildValue("()"), kwd_dict);
PyObject* elements = SplayTree__pre_order(self, Py_BuildValue("(O)", reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(bt->root_idx)])->right));
for (int i=0; i<PyList_Size(elements); i++) {
SelfBalancingBinaryTree_insert(other->sbbt, Py_BuildValue("(OO)", reinterpret_cast<TreeNode*>( PyList_GetItem(elements, i))->key, reinterpret_cast<TreeNode*>( PyList_GetItem(elements, i))->data));
}
for (int j=PyList_Size(elements)-1; j>-1; j--) {
tup = SelfBalancingBinaryTree_search(self->sbbt, Py_BuildValue("(O)", reinterpret_cast<TreeNode*>( PyList_GetItem(elements, j))->key), kwd_parent);
e = PyTuple_GetItem(tup, 0);
p = PyTuple_GetItem(tup, 1);
bt->tree->_one_dimensional_array->_data[PyLong_AsLong(e)] = Py_None;
}
reinterpret_cast<TreeNode*>(bt->tree->_one_dimensional_array->_data[PyLong_AsLong(bt->root_idx)])->right = Py_None;
}

return reinterpret_cast<PyObject*>(other);
}

static struct PyMethodDef SplayTree_PyMethodDef[] = {
{"insert", (PyCFunction) SplayTree_insert, METH_VARARGS, NULL},
{"delete", (PyCFunction) SplayTree_delete, METH_VARARGS, NULL},
{"join", (PyCFunction) SplayTree_join, METH_VARARGS, NULL},
{"split", (PyCFunction) SplayTree_split, METH_VARARGS, NULL},
{NULL}
};


static PyMemberDef SplayTree_PyMemberDef[] = {
{"tree", T_OBJECT_EX, offsetof(SplayTree, tree), 0, "tree"},
{NULL} /* Sentinel */
Expand Down Expand Up @@ -270,4 +339,6 @@ static PyTypeObject SplayTreeType = {
/* tp_new */ SplayTree___new__,
};



#endif
2 changes: 1 addition & 1 deletion pydatastructs/trees/binary_trees.py
Original file line number Diff line number Diff line change
Expand Up @@ -1145,7 +1145,7 @@ def join(self, other):
self.tree[self.root_idx].right = \
other.root_idx + idx_update

def split(self, x):
def split(self, x, unused):
"""
Splits current splay tree into two trees such that one tree contains nodes
with key less than or equal to x and the other tree containing
Expand Down
27 changes: 14 additions & 13 deletions pydatastructs/trees/tests/test_binary_trees.py
Original file line number Diff line number Diff line change
Expand Up @@ -535,19 +535,20 @@ def _test_SplayTree(backend):
# assert [node.key for node in in_order] == [20, 30, 50, 55, 100, 200, 1000, 2000]
# assert [node.key for node in pre_order] == [200, 55, 50, 30, 20, 100, 2000, 1000]

# s = t.split(200)

# trav4 = BinaryTreeTraversal(s)
# in_order = trav4.depth_first_search(order='in_order')
# pre_order = trav4.depth_first_search(order='pre_order')
# assert [node.key for node in in_order] == [1000, 2000]
# assert [node.key for node in pre_order] == [2000, 1000]

# trav5 = BinaryTreeTraversal(t)
# in_order = trav5.depth_first_search(order='in_order')
# pre_order = trav5.depth_first_search(order='pre_order')
# assert [node.key for node in in_order] == [20, 30, 50, 55, 100, 200]
# assert [node.key for node in pre_order] == [200, 55, 50, 30, 20, 100]
s = t.split(200, SplayTree(backend=backend))
assert str(s) == "[(1, 2000, 2000, None), (None, 1000, 1000, None)]"

trav4 = BinaryTreeTraversal(s, backend=backend)
in_order = trav4.depth_first_search(order='in_order')
pre_order = trav4.depth_first_search(order='pre_order')
assert [node.key for node in in_order] == [1000, 2000]
assert [node.key for node in pre_order] == [2000, 1000]

trav5 = BinaryTreeTraversal(t, backend=backend)
in_order = trav5.depth_first_search(order='in_order')
pre_order = trav5.depth_first_search(order='pre_order')
assert [node.key for node in in_order] == [20, 30, 50, 55, 100, 200]
assert [node.key for node in pre_order] == [200, 55, 50, 30, 20, 100]

def test_SplayTree():
_test_SplayTree(Backend.PYTHON)
Expand Down

0 comments on commit ca0c042

Please sign in to comment.