@@ -588,6 +588,77 @@ static PyObject* BinarySearchTree_rank(BinarySearchTree* self, PyObject* args) {
588
588
return PyLong_FromLong (r);
589
589
}
590
590
591
+ static PyObject* BinarySearchTree_select (BinarySearchTree* self, PyObject* args) {
592
+ long i = PyLong_AsLong (PyObject_GetItem (args, PyZero));
593
+ i = i - 1 ;
594
+ if (i < 0 ) {
595
+ PyErr_SetString (PyExc_ValueError, " Expected a positive integer" );
596
+ return NULL ;
597
+ }
598
+ BinaryTree* bt = self->binary_tree ;
599
+ if (i >= bt->tree ->_num ) {
600
+ PyErr_SetString (PyExc_ValueError, " Integer passed to select() is greater than the size of the tree." );
601
+ return NULL ;
602
+ }
603
+ PyObject* walk = bt->root_idx ;
604
+ while (walk != Py_None) {
605
+ long l = BinarySearchTree_left_size (self, reinterpret_cast <TreeNode*>(bt->tree ->_one_dimensional_array ->_data [PyLong_AsLong (walk)]));
606
+ if (i == l) {
607
+ return bt->tree ->_one_dimensional_array ->_data [PyLong_AsLong (walk)];
608
+ }
609
+ PyObject* left_walk = reinterpret_cast <TreeNode*>(bt->tree ->_one_dimensional_array ->_data [PyLong_AsLong (walk)])->left ;
610
+ PyObject* right_walk = reinterpret_cast <TreeNode*>(bt->tree ->_one_dimensional_array ->_data [PyLong_AsLong (walk)])->right ;
611
+ if (left_walk == Py_None && right_walk==Py_None) {
612
+ PyErr_SetString (PyExc_IndexError, " The traversal is terminated due to no child nodes ahead." );
613
+ return NULL ;
614
+ }
615
+ if (i < l) {
616
+ if (!PyCallable_Check (bt->comparator )) {
617
+ PyErr_SetString (PyExc_ValueError, " comparator should be callable" );
618
+ return NULL ;
619
+ }
620
+ PyObject* arguments = Py_BuildValue (" OO" , reinterpret_cast <TreeNode*>(bt->tree ->_one_dimensional_array ->_data [PyLong_AsLong (left_walk)])->key , reinterpret_cast <TreeNode*>(bt->tree ->_one_dimensional_array ->_data [PyLong_AsLong (walk)])->key );
621
+ PyObject* cres = PyObject_CallObject (bt->comparator , arguments);
622
+ Py_DECREF (arguments);
623
+ if (!PyLong_Check (cres)) {
624
+ PyErr_SetString (PyExc_TypeError, " bad return type from comparator" );
625
+ return NULL ;
626
+ }
627
+ long long comp = PyLong_AsLongLong (cres);
628
+
629
+ if (left_walk != Py_None && comp) {
630
+ walk = left_walk;
631
+ }
632
+ else {
633
+ walk = right_walk;
634
+ }
635
+ }
636
+ else {
637
+ if (!PyCallable_Check (bt->comparator )) {
638
+ PyErr_SetString (PyExc_ValueError, " comparator should be callable" );
639
+ return NULL ;
640
+ }
641
+ PyObject* arguments = Py_BuildValue (" OO" , reinterpret_cast <TreeNode*>(bt->tree ->_one_dimensional_array ->_data [PyLong_AsLong (right_walk)])->key , reinterpret_cast <TreeNode*>(bt->tree ->_one_dimensional_array ->_data [PyLong_AsLong (walk)])->key );
642
+ PyObject* cres = PyObject_CallObject (bt->comparator , arguments);
643
+ Py_DECREF (arguments);
644
+ if (!PyLong_Check (cres)) {
645
+ PyErr_SetString (PyExc_TypeError, " bad return type from comparator" );
646
+ return NULL ;
647
+ }
648
+ long long comp = PyLong_AsLongLong (cres);
649
+
650
+ if (right_walk != Py_None && (!comp)) {
651
+ walk = right_walk;
652
+ }
653
+ else {
654
+ walk = left_walk;
655
+ }
656
+ i = i - (l + 1 );
657
+ }
658
+ }
659
+ Py_RETURN_NONE; // This is a dummy return
660
+ }
661
+
591
662
static struct PyMethodDef BinarySearchTree_PyMethodDef[] = {
592
663
{" insert" , (PyCFunction) BinarySearchTree_insert, METH_VARARGS | METH_KEYWORDS, NULL },
593
664
{" delete" , (PyCFunction) BinarySearchTree_delete, METH_VARARGS | METH_KEYWORDS, NULL },
@@ -599,6 +670,7 @@ static struct PyMethodDef BinarySearchTree_PyMethodDef[] = {
599
670
{" _lca_2" , (PyCFunction) BinarySearchTree__lca_2, METH_VARARGS, NULL },
600
671
{" lowest_common_ancestor" , (PyCFunction) BinarySearchTree_lowest_common_ancestor, METH_VARARGS, NULL },
601
672
{" rank" , (PyCFunction) BinarySearchTree_rank, METH_VARARGS, NULL },
673
+ {" select" , (PyCFunction) BinarySearchTree_select, METH_VARARGS, NULL },
602
674
{NULL }
603
675
};
604
676
0 commit comments