我正在浏览从二叉搜索树中删除节点的代码,我有点困惑
Node deleteRec(Node root, int key)
{
/* Base Case: If the tree is empty */
if (root == null) return root;
/* Otherwise, recur down the tree */
if (key < root.key)
root.left = deleteRec(root.left, key);
else if (key > root.key)
root.right = deleteRec(root.right, key);
// if key is same as root's key, then This is the node
// to be deleted
else
{
// node with only one child or no child
if (root.left == null)
return root.right;
else if (root.right == null)
return root.left;
// node with two children: Get the inorder successor (smallest
// in the right subtree)
root.key = minValue(root.right);
// Delete the inorder successor
root.right = deleteRec(root.right, root.key);
}
return root;
}
为什么我们需要在几个地方的root.left
和root.right
变量中存储函数调用的结果?由于root
的值,即引用被传递给函数,后续调用中的任何更改都将自动更新树,不是吗?那么为什么要将值存储在变量中呢?为了明确我的观点,下面是另一段代码
// A recursive function used by topologicalSort
void topologicalSortUtil(int v, boolean visited[],
Stack stack)
{
// Mark the current node as visited.
visited[v] = true;
Integer i;
// Recur for all the vertices adjacent to this
// vertex
Iterator<Integer> it = adj[v].iterator();
while (it.hasNext())
{
i = it.next();
if (!visited[i])
topologicalSortUtil(i, visited, stack);
}
// Push current vertex to stack which stores result
stack.push(new Integer(v));
}
这里堆栈正在传递给函数,我们只是在进一步的函数调用中一次又一次地使用它,因为我们知道堆栈将继续在调用之间进行更新。
我错过了什么或者我理解错了什么?有人可以帮我理解。谢谢!!
答案 0 :(得分:1)
不同递归级别的root
对象不是同一个对象。
当您向下递归树时,请使用deleteRec
或root.left
作为第一个参数调用root.right
。因此,下一级递归会将左子树或右子树的根视为其“根”。
这与为stack
的第三个参数传递的topologicalSortUtil
变量不同:此变量始终保持不变,因此所有级别都可以访问相同的对象。
答案 1 :(得分:1)
删除节点时,必须拉出其下的树部分。否则,您将删除该节点及其所有后代,这是不正确的。
答案 2 :(得分:1)
删除树的节点时,可能需要更新父节点的左或右指针。最简单的情况是当删除的not不是叶子时:在这种情况下,指向它的链接必须设置为null。
如果另外,删除的节点恰好是根节点,则必须更新指向根的指针。
当您调用deleteRec方法时,您无法事先知道返回的值是否与第一个参数相同。
答案 3 :(得分:1)
您的deleteRec
方法会收到二叉树的Node
并修改树。但是,每个递归调用都会传递给树的不同Node
。这与您的第二个示例不同,后者会向每个递归调用传递相同的Stack
。
现在,当deleteRec
找到它应该从树中删除的Node
时(当前递归调用的root
为Node
时应该是Node
已删除),它无法从树中删除Node
。它必须修改已删除的Node
的父Node
,才能从树中删除Node
。这就是递归调用返回时会发生什么,并且该调用返回的root.left
被分配给root.right
或read_excel
。