一个Leaf
结构看起来像这样:
typedef struct struct_t {
int data;
Leaf * left; //These allow structs to be chained together where each node
Leaf * right; //has two pointers to two more nodes, causing exponential
} Leaf; //growth.
该函数接受一个指向我们调用的 Leaf 的指针R
和一些要搜索的数据,它返回一个指向 Leaf 的指针
Leaf *findLeaf(Leaf *R,int data){
这段代码决定了我们应该向左还是向右,这棵树是有序的,因为插入函数遵循相同的向左和向右规则。
if(R->data >= data ){
这是函数递归性质的边缘情况,如果我们已经到达树中的最后一个节点,称为叶子,则返回该叶子。
递归函数的边缘情况具有结束递归并返回结果的任务。没有这个,函数将无法完成。
if(R->left == NULL) return R;
这就是我们遍历树的方式,在这里,我们沿着左侧向下遍历,因为数据更大。(较大的数据总是插入到左边以保持有序。)现在我们用 调用 findLeaf() R->left
,但想象一下,如果我们在下一次调用中再次到达这一点。
它将R->left->left
参考第一次调用。如果数据小于我们正在操作的当前节点,我们将改为正确。
else return findLeaf(R->left,data);
现在我们处于数据小于当前节点的情况,所以我们走对了。
} else {
这与左边完全一样。
if(R->right == NULL) return R;
else return findLeaf(R->right,data);
}
}
最后,函数的返回可以概念化为R->right->right->left->NULL
.
让我们获取这棵树并使用 findLeaf() 对其进行操作;
findLeaf(Leaf * root, 4) //In this example, root is already pointing to (8)
我们从树的顶部开始,其中包含 8。
首先,我们检查R->data >= data
我们知道R->data
的位置 is(8)
和data
is (4)
。由于我们知道data
小于R->data
(当前节点),我们输入if
语句。
这里我们对左边的 Leaf 进行操作,检查它是否为NULL
. 它不是,所以我们跳到else
.
现在我们 return findLeaf(R->left, data);
,但要返回它,我们必须先解决它。这导致我们进入第二次迭代,我们将在其中进行比较并重(3)
试(4)
。
再过一遍整个过程,我们会比较(6) to (4)
,最后在比较的时候找到我们的节点(4) to (4)
。现在我们将回溯该函数并返回如下链:
R(8)->(3)->(6)->(4)
编辑:另外,巧合的是,我写了一篇关于遍历链表的博客文章,在这里解释了二叉搜索树的性质。