我发现为树数据结构编写函数的最有效形式通常是以下伪代码格式。
function someActionOnTree() {
return someActionOnTree(root)
}
function someActionOnTree (Node current) {
if (current is null) {
return null
}
if (current is not the node I seek) {
//logic for picking the next node to move to
next node = ...
next node = someActionOnTree(next node)
}
else {
// do whatever you need to do with current
// i.e. give it a child, delete its memory, etc
current = ...
}
return current;
}
此递归函数在数据结构的顶点集上递归。对于算法的每次迭代,它要么寻找一个节点来递归函数,然后用算法在该节点上的迭代值覆盖数据结构对该节点的引用。否则,它会覆盖节点的值(并可能执行一组不同的逻辑)。最后,该函数返回对参数节点的引用,这对于覆盖步骤至关重要。
这通常是我为 C++ 中的树数据结构找到的最有效的代码形式。这些概念也适用于其他结构 - 您可以使用这种形式的递归,其中返回值始终是对数据结构平面表示中固定点的引用(基本上,始终返回应该在您所在位置的任何内容) '正在看)。
下面是这种风格在二叉搜索树删除函数中的应用,以修饰我的观点。
function deleteNodeFromTreeWithValue( value ) {
return deleteNodeFromTree(root, value)
}
function deleteNodeFromTree(Node current, value) {
if (current is null) return null
if (current does not represent value) {
if (current is greater than my value) {
leftNode = deleteNodeFromTree(leftNode, value)
} else {
rightNode = deleteNodeFromTree(rightNode, value)
}
}
else {
free current's memory
current = null
}
return current
}
显然,还有许多其他方法可以编写此代码,但根据我的经验,事实证明这是最有效的方法。请注意,覆盖指针并没有真正影响性能,因为硬件已经缓存了节点。如果您正在考虑提高搜索树的性能,我建议您研究专门的树,例如自平衡树(AVL 树)、B 树、红黑树等。