我正在研究SequentialSearchST
的代码,该代码由包含键值对的无序链接列表实现。我被困在下面的删除方法,该方法试图找到并删除包含给定键的节点。
public void delete(Key k) {
first = delete(first, k); // first refers to the first node in the list
}
public Node delete(Node x, Key k) {
if (x == null) return null;
if (k.equals(x.key)) { return x.next; }
x.next = delete(x.next, k);
return x;
}
如何,我可以开发和理解这个递归函数,还说它的递归和归纳是唯一相同的东西,我能从这个概念中得到帮助吗?如果是,那怎么样?
谢谢,
答案 0 :(得分:1)
这种递归实现可以重写为循环。不幸的是,所提供的实现中的解决方案的细微差别不能完全表示为循环。
首先要了解每种方法的作用。第一种方法是外部方法 - 它处理列表为空的情况。第二种方法是内部方法,以及实际递归的方法。内部方法的作用是找到与给定键匹配的元素,并返回列表中的下一个元素。
如果我们有一个包含[1, 4, 3, 7, 5]
的列表并希望删除元素3
,我们需要做的就是将元素4
上的下一个字段设置为元素7
(元素3
之后的元素)。
带注释的调用/指令堆栈(假设第8行意为x.next = delete(x.next, k)
)类似于:
delete(Key<3> k)
delete(Node<1> x, Key<3> k)
if (x == null) // x is not null
if (k.equals(x.key)) // x.key is not k
delete(Node<4> x, Key<3> k)
if (x == null) // x is not null
if (k.equals(x.key)) // x.key is not k
delete(Node<3> x, Key<3> k)
if (x == null) // x is not null
if (k.equals(x.key)) // x.key is k!
return x.next // Node<7>
x.next = result // Node<4>.next = Node<7> (was Node<3>)
return x // Node<4>
x.next = result // Node<1>.next = Node<4> (no change)
return x // Node<1>
first = result // first = Node<1> (no change)
请注意,如果找到了提供的密钥,则if (x == null)
检查永远不会成立。这是因为如果我们找到我们要删除的元素,我们就不会进行递归 - 我们不会再次调用delete
,因为我们会从该方法调用返回。只有在找不到密钥时才会进行该检查,并且您到达列表的末尾 - 因此x.next
将为空。
另请注意,列表中的每个next
引用都会被重写。但是,next
引用在大多数情况下都不会更改,因为它已更新为引用已引用的节点。
如果使用相同的列表,我们想要删除元素2
,删除过程将是这样的:
delete(Key<2> k)
delete(Node<1> x, Key<2> k)
if (x == null) // x is not null
if (k.equals(x.key)) // x.key is not k
delete(Node<4> x, Key<2> k)
if (x == null) // x is not null
if (k.equals(x.key)) // x.key is not k
delete(Node<3> x, Key<2> k)
if (x == null) // x is not null
if (k.equals(x.key)) // x.key is not k
delete(Node<7> x, Key<2> k)
if (x == null) // x is not null
if (k.equals(x.key)) // x.key is not k
delete(Node<5> x, Key<2> k)
if (x == null) // x is not null
if (k.equals(x.key)) // x.key is not k
delete(null x, Key<2> k)
if (x == null) // x is null!
return null
x.next = result // Node<5>.next = null (no change)
return x // Node<5>
x.next = result // Node<7>.next = null (no change)
return x // Node<7>
x.next = result // Node<3>.next = null (no change)
return x // Node<3>
x.next = result // Node<4>.next = null (no change)
return x // Node<4>
x.next = result // Node<1>.next = null (no change)
return x // Node<1>
first = result // first = Node<1> (no change)
没有任何改变,因为找不到给定的密钥。