以下是我的链接列表的类定义。我运行一个测试程序,创建一个新的LinkedList并插入数字“3,2,1”,然后打印列表。这很好用。但是,当我尝试删除“3”或“2”时,删除方法永远不会完成。当我尝试删除“1”时,它只打印出完整的列表,就像没有删除任何内容一样。
public class LinkedListTest implements LinkedList {
private Node head;
public LinkedListTest(){
head = new Node();
}
public void insert(Object x){
if (lookup(x).equals(false)){
if (head.data == null)
head.data = x;
else{
//InsertLast
Node temp = head;
while (temp.next != null){
temp = temp.next;
}
Node NewNode = new Node();
NewNode.data = x;
NewNode.next = null;
temp.next = NewNode;
}
}
//Runtime of insert method will be n, where n is the number of nodes
}
public void delete(Object x){
if (lookup(x).equals(true)){
if (head.data == x)
head = head.next;
else{
Node temp = head;
while (temp.next != null){
if ((temp.next).data == x)
temp.next = (temp.next).next;
else
temp = temp.next;
}
}
}
}
public Object lookup(Object x){
Node temp = head;
Boolean search = false;
if (head.data == x)
search = true;
while (temp.next != null){
if (temp.data == x){
search = true;
}
else{
temp = temp.next;
}
}
return search;
}
public boolean isEmpty(){
if (head.next == null && head.data == null)
return true;
else
return false;
}
public void printList(){
Node temp = head;
System.out.print(temp.data + " ");
while (temp.next != null){
temp = temp.next;
System.out.print(temp.data + " ");
}
}
}
编辑:这是节点类:
public class Node {
public Object data;
public Node next;
public Node(){
this.data = null;
this.next = null;
}
}
答案 0 :(得分:3)
这里有一些问题。
第一个大问题是,在lookup()
和delete()
方法中,当成功条件发生时,您不会中断循环。这就是你的程序挂起的原因;它处于无限循环中。
值得注意的是,这一点是一个令人难以置信的糟糕做法不使用所有if / else语句的花括号。没有理由不这样做,并且当你不这样做时它可以很容易地引入bug。
你应该在lookup()
中:
if (head.data == x) {
search = true;
} else {
while (temp.next != null){
if (temp.data == x){
search = true;
break;
} else {
temp = temp.next;
}
}
}
和delete()
:
if (head.data == x) {
head = head.next;
} else {
Node temp = head;
while (temp.next != null) {
if (temp.next.data.equals(x)) {
temp.next = temp.next.next;
break;
} else {
temp = temp.next;
}
}
}
现在这将产生你所期望的:
public static void main( String[] args )
{
LinkedListTest llt = new LinkedListTest();
llt.insert(1);
llt.insert(2);
llt.insert(3);
llt.printList();
System.out.println();
llt.delete(2);
llt.printList();
}
输出:
1 2 3
1 3
但是,这不会暴露您的第二个更大的问题。在查看节点的==
时,您正在使用data
比较参考值。
由于自动装箱小整数值的副作用,此刻“正常”;你得到了相同的对象引用。 (由于字符串池,字符串文字也会“起作用”)。有关详细信息,请查看How do I compare Strings in Java和When comparing two integers in java does auto-unboxing occur
让我们来看看:
public static void main( String[] args )
{
LinkedListTest llt = new LinkedListTest();
llt.insert(1000);
llt.insert(2000);
llt.insert(2000);
llt.insert(3000);
llt.printList();
System.out.println();
llt.delete(2000);
llt.printList();
}
输出:
1000 2000 2000 3000
1000 2000 2000 3000
lookup()
停止工作,允许插入副本。 delete()
也停止了工作。
这是因为int
超过127个自动框对独特Integer
个对象而不是缓存对象(请参阅上面链接的SO问题以获得完整说明)。
您使用==
比较data
所持有的值的任何地方都需要更改为使用.equals()
。
if (temp.data.equals(x)) {
解决了这些技术问题后,您的程序就可以运行了。还有其他事情你应该考虑。跳出来的两个是:
lookup
应返回boolean
。lookup()
delete()
lookup
本身作为一种单独的方法是一种相当低效的方法;插入遍历整个列表两次。 答案 1 :(得分:0)
首先为什么查找会返回一个对象?将其更改为布尔值。
lookup()
中的“while”循环也没有进展。你需要删除“其他”。
你的删除功能似乎很好。
答案 2 :(得分:-1)
我觉得你有些不对劲。
首先,当您使用LinkedList时,您尝试实现的所有功能都已存在。
此外你的风格相对较差。例如,为什么要使用WrapperClass布尔值进行查找?
在一种方法中将等等功能与 get 结合起来并不是一个好主意。将其拆分为两种方法,让包含只返回一个布尔值并测试列表中是否存在元素。让我们搜索并返回一个元素。
除此之外,您尝试通过相等比较对象。如果你没有覆盖equals,你就不能删除任何东西,因为equals需要引用相等而不是大多数时间。
我强烈建议你购买一本java书或其他东西,以提高你的整体知识..