我的形式是Sedgewick的书中的代码:Algorithms:
private Node deleteMin(Node x) {
if (x.left == null) return x.right;
x.left = deleteMin(x.left);
x.N = size(x.left) + size(x.right) + 1;
return x;
}
public void delete(Key key) {
root = delete(root, key);
}
private Node delete(Node x, Key key) {
if (x == null) return null;
int cmp = key.compareTo(x.key);
if (cmp < 0) x.left = delete(x.left, key);
else if (cmp > 0) x.right = delete(x.right, key);
else {
if (x.right == null) return x.left;
if (x.left == null) return x.right;
Node t = x;
x = min(t.right);
x.right = deleteMin(t.right);
x.left = t.left;
}
x.N = size(x.left) + size(x.right) + 1;
return x;
}
基本上我想知道递归在树中是如何工作的,因为我想将此方法转换为找到要旋转它的节点,直到成为叶子然后将其删除。
public void delete(Key key) {
root = delete(root, key);
}
private Node delete(Node x, Key key) {
if (x == null) return null;
int cmp = key.compareTo(x.key);
if (cmp < 0) x.left = delete(x.left, key);
else if (cmp > 0) x.right = delete(x.right, key);
else {
//if is a leaf delete it
//if has one child rotate it
//if it has two children compare some value
//of the children choose the bigger and rotate
}
x.N = size(x.left) + size(x.right) + 1;
return x;
}
private Node rotateLeft(Node h)
{
Node x = h.right;
h.right = x.left;
x.left = h;
return x;
}
private Node rotateRight(Node h)
{
Node x = h.left;
h.left = x.right;
x.right = h;
return x;
}
我尝试了一些东西,但它抛出一个空指针异常。我设法迭代地做了但是 指向节点的指针没有更新,所以我丢失了树。有人能告诉我它是如何工作的,所以我可以正确地修改它吗?
答案 0 :(得分:2)
基本上我想知道递归在树中是如何工作的
递归“工作”的方式与其在任何其他算法中的工作方式相同。一个方法最终直接或间接地调用自己......并且在这个过程中做了一些有用的事情。
在这种特殊情况下,有用的东西是Node delete(Node, Key)
通过提供Node
(现有的或新的)1)从输入Node
给出的子树中删除密钥不包含Key
和2)仍然是一个格式良好的二叉树。
完整的解释将是漫长而乏味的,可能需要在树木之前和之后创建大量图形。从SO答案 1 来预期太多了。如果您对代码的特定部分有特定问题,则需要特别询问......
...有人能告诉我它是如何工作的,所以我可以正确地修改它吗?
如果“它”代表您的代码,则可能不是。您实际上是在要求某人对您的(非工作)代码进行反向工程,弄清楚您编写代码时的心理概念,并弄清楚如何将代码转换为有效的代码。 (我没试过......)
如果“it”表示Sedgewick代码,请参见上文。 (包括你的代码有什么意义?)
1 - 如果有人花时间为你做这件事,你很可能会回来说“实际上,我已经理解了大部分内容。我没有得到的一件事就是。 ..“。