所以我试图从java中的链表中删除一个项目。我没有使用java的预定义LL,但我正在使用自己的LL。
我知道删除项目的概念是遍历链接并逐一比较列表中的数据。
所以这就是我想出来的,但它不起作用!
public void delStudent(int regN) {
Node current = head;
Node q = head;
if (current.getStudent().getRegN() == regN) {
head = head.link;
}
for (int i = 0; i < this.length() - 1; i++) {
if (current.getStudent().getRegN() != regN) {
current = current.link;
q = current;
}
}
q.link= current.link.link;
}
答案 0 :(得分:1)
好吧,如果你的列表是空的,那么在开头执行if语句会立即给出一个NullPointerException(因为current将为null)。通常,对于LinkedList删除方法,您必须考虑三种情况:size == 0,size == 1,size&gt; 1(其中size是链接列表中的节点数)。
public void delStudent(int regN) {
Node current = head;
Node previous = head;
while (current != null ){ // keep traversing till end of list
if (current.getStudent().getRegN() == regN) { // found it!
previous.link = current.link; // relink
if (current == head){ // edge case : removed first element
head = current.link; // move head forward.
}
break;
} else {
previous = current;
current = current.link;
}
}
}
上面的代码假设regN是唯一的,并且只有一个学生拥有该regN。希望这会有所帮助。
答案 1 :(得分:0)
错误是(我认为)在这三行中:
current = current.link;
q = current;
(您将q
设置为与current
相同)和
q.link= current.link.link;
(也许还可以使用length()
,具体取决于它的实现)
要了解为什么让我们看看如何更详细地删除:
让我们考虑列表中有三个节点x-&gt; y-&gt; z,你想要删除y。
为此,您需要设置x.link = z
。
回到你的例子,这意味着变量q
应该在current
之前存储元素,然后删除current
可以通过
q.link = current.link;
为了让q
成为current
的前身,你必须颠倒上面的两行,即使用
q = current;
current = current.link;
为什么我要根据length
的实施情况来说?如果执行length只是返回一些数字,只要你向列表中添加一个值就会增加,你也应该在删除它时减少它。如果长度遍历列表以便找到元素的数量,那么它可以,但效率不高。
最后一条评论:当没有给定regN
的元素时,您的代码无法正常工作(即使我上面已解释过这些修补程序)。为什么?因为你总是删除一个元素。而且,您可能想重新考虑循环内部的逻辑。目前,如果要删除的元素是第二个,并且有1000000个元素,则将运行该循环近1000000次。
答案 2 :(得分:0)
当您检查每个节点时,您需要删除节点或在找到匹配后中断。您需要维护上一个节点的节点,以便在找到匹配项后能够删除当前节点。
我刚刚意识到你正在尝试使用Node q
for (int i = 0; i < this.length() - 1; i++) {
if (current.getStudent().getRegN() != regN) {
q = current;
current = current.link;
} else{ //we have a match
//remove the link to the current item
q.link = current.link;
break;
}
如果您使用的是双向链接列表,则可以使用node.prev()。link = current.link;