简体   繁体   English

链接列表删除方法

[英]Linked List Delete Method

The following is a class definition for my Linked List. 以下是我的链接列表的类定义。 I run a test program that creates a new LinkedList and inserts the numbers "3, 2, 1" and then prints the list. 我运行一个测试程序,创建一个新的LinkedList并插入数字“3,2,1”,然后打印列表。 This works fine. 这很好用。 However, when I try and delete "3" or "2," the delete method never completes. 但是,当我尝试删除“3”或“2”时,删除方法永远不会完成。 When I try and delete "1," it just prints out the complete list as if nothing had been deleted. 当我尝试删除“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 + " ");
    }

}
}

EDIT: Here is the node class: 编辑:这是节点类:

public class Node {
public Object data;
public Node next;

public Node(){
    this.data = null;
    this.next = null;
}
}

There are a few issues here. 这里有一些问题。

The first big issue is that in your lookup() and your delete() methods, you don't break out of your loops when a successful condition occurs. 第一个大问题是在lookup()delete()方法中,当成功条件发生时,不会中断循环。 This is why your program is hanging; 这就是你的程序挂起的原因; it's in an infinite loop. 它处于无限循环中。

It's also worth noting a this point is that it's an incredibly bad practice not to use curly braces with all if/else statements. 同样值得注意的是,这一点是一种非常糟糕的做法,不使用所有if / else语句的花括号。 There's no reason not to do so, and it can introduce bugs easily when you don't. 没有理由不这样做,并且当你不这样做时它可以很容易地引入bug。

in lookup() you should have: lookup()你应该有:

if (head.data == x) {
    search = true;
} else {
    while (temp.next != null){
        if (temp.data == x){
            search = true;
            break;
        } else {
            temp = temp.next;
        }
    }
}

and in delete() : 并在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;
        }
    }
}

Now this will produce what you expect: 现在这将产生你所期望的:

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();
}

Output: 输出:

1 2 3 1 2 3
1 3 1 3

However, that doesn't expose your second, larger issue. 但是,这不会暴露您的第二个更大的问题。 You're comparing reference values using == when looking at the node's data . 您在查看节点data时使用==比较参考值

This "works" at the moment because of a side-effect of auto-boxing small integer values; 由于自动装箱小整数值的副作用,此刻“有效”; you're getting the same object references. 你得到了相同的对象引用。 (String literals would also "work" because of the string pool). (由于字符串池,字符串文字也会“起作用”)。 For more info on this, look at How do I compare Strings in Java and When comparing two integers in java does auto-unboxing occur 有关这方面的更多信息,请参阅如何比较Java中的字符串比较java中的两个整数时自动取消装箱发生

Let's look at this: 我们来看看这个:

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();
}

Output: 输出:

1000 2000 2000 3000 1000 2000 2000 3000
1000 2000 2000 3000 1000 2000 2000 3000

lookup() stopped working, allowing a duplicate to be inserted. lookup()停止工作,允许插入副本。 delete() stopped working as well. delete()停止了工作。

This is because int values over 127 auto-box to unique Integer objects rather than cached ones (see the linked SO question above for a full explanation). 这是因为int值超过127自动框到唯一的Integer对象而不是缓存的对象(请参阅上面链接的SO问题以获得完整的解释)。

Anywhere you're using == to compare the value held by data needs to be changed to use .equals() instead. 您正在使用的任何地方==比较data所持有的值需要更改为使用.equals()

if (temp.data.equals(x)) {

With those technical issues solved, your program will work. 解决了这些技术问题后,您的程序将正常运行。 There's other things that you should consider though. 还有其他事情你应该考虑。 The two that jump right out are: 跳出来的两个是:

  • lookup should return a boolean . lookup应该返回一个boolean
  • There's no need to call lookup() in delete() 没有必要在delete()调用lookup() delete()
  • lookup itself is a fairly inefficient approach as a separate method; lookup本身作为一种单独的方法是一种相当低效的方法; An insert iterates through the entire list twice. 插入遍历整个列表两次。

First of all why does lookup return an object? 首先为什么查找返回一个对象? change it to boolean. 将其更改为布尔值。 also your "while" loop in lookup() doesn't advance. lookup()中的“while”循环也不会前进。 you need to remove the "else". 你需要删除“其他”。 your delete function seems fine though. 你的删除功能似乎很好。

I think you got quite some things wrong. 我觉得你有些不对劲。

First of all, when you use LinkedList all of the functionality you tried to implement already exists. 首先,当您使用LinkedList时,您尝试实现的所有功能都已存在。

Furthermore your style is relatively bad. 此外,你的风格相对较差。 For example, why do you use the WrapperClass Boolean for lookup? 例如,为什么要使用WrapperClass布尔值进行查找?

Combining functionality like contains with something like get in one method is not a good idea. 将像contains这样的功能与get in one方法结合起来并不是一个好主意。 Split this up in two methods, let contains just return a boolean and test if an element exists in the list. 将它拆分为两个方法,let contains只返回一个布尔值并测试列表中是否存在元素。 Let get search and return for an element. 让我们搜索并返回一个元素。

In addition to this you try to compare the Objects via equal. 除此之外,您尝试通过相等比较对象。 If you have not overwritten equals you can not delete anything ever, because equals needs reference equality which is not given most times. 如果你没有覆盖equals,你就不能删除任何东西,因为equals需要引用相等而不是大多数时候给出的。

I would highly recommend that you buy a java book or something to improve your overall knowledge.. 我强烈建议你购买一本java书或其他东西来提高你的整体知识。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM