Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 删除重复的链接列表_Java_Linked List - Fatal编程技术网

Java 删除重复的链接列表

Java 删除重复的链接列表,java,linked-list,Java,Linked List,我试图实现一种方法,从链表中删除所有重复项。我已经设法照顾好了尾巴。换句话说,如果尾部的数据是重复的,程序不会抛出异常错误。现在,我正在尝试处理头部,这样,如果头部的数据是重复的,我想设置头部=头部。下一步,这样重复的数据就不再在链接列表中。但是,我的方法deleteplicates不处理头。有人有解决这个问题的建议吗 class Node { private Node next = null; private int data; publi

我试图实现一种方法,从链表中删除所有重复项。我已经设法照顾好了尾巴。换句话说,如果尾部的
数据
是重复的,程序不会抛出
异常错误
。现在,我正在尝试处理头部,这样,如果
头部
的数据是重复的,我想设置
头部
=
头部。下一步
,这样重复的数据就不再在链接列表中。但是,我的方法
deleteplicates
不处理
。有人有解决这个问题的建议吗

class Node {
        private Node next = null; 
        private int data; 

        public Node(int d) {
            data = d; 
        }

        void appendToTail(int d) {
            Node end = new Node(d); 
            Node n = this; 

            while(n.next != null) {
                n = n.next; 
            }
            n.next = end; 
        }

        void print() {
            Node n = this; 
            while(n != null) {
                System.out.println(n.data); 
                n = n.next; 
            }
        }

        Node deleteDuplicates(Node head, int d) {
            Node n = head;
            if(n.data == d) {
                head = head.next; 
                n = n.next; 
            }
            while(n != null) {
                if(n.next.data == d) {
                    if(n.next == null && n.next.data == d) {
                        return head;
                    }
                    n.next = n.next.next;
                }
                n = n.next; 
            }
            return head; 
        }

        public static void main(String [] args) {
            Node x = new Node(9); 
            x.appendToTail(5);
            x.appendToTail(9);
            x.appendToTail(6);
            x.appendToTail(9);  
            x.appendToTail(7);
            x.appendToTail(9);  
            x.appendToTail(8); 
            x.appendToTail(9); 
            x.deleteDuplicates(x, 9); 
            x.print(); 
        }   
    }

如果您只需要一个唯一对象的容器,那么最好的方法是让这些对象实现.equals()和.hashCode()方法,这样您就可以使用来处理唯一性逻辑

相等可以很容易地实现为所有类的字段相等和来自所有类的字段哈希代码串联的哈希的哈希代码的相加

如果你出于某种原因需要将它们链接起来,有没有适合你的

整数示例:

LinkedHashSet<Integer> myCollection = new LinkedHashSet<Integer>();
myCollection.add(5);
myCollection.add(3);
myCollection.add(2);
myCollection.add(5);
myCollection.add(2);
System.out.println(myCollection);
// prints [5, 3, 2]
LinkedHashSet myCollection=新建LinkedHashSet();
添加(5);
myCollection.add(3);
myCollection.add(2);
添加(5);
myCollection.add(2);
System.out.println(myCollection);
//印刷品[5,3,2]

可以找到一个自定义类的示例。

代码中的问题是删除后您没有重新分配头。 如果你修改如下,我认为你的头部删除问题将得到解决

x=x.deleteDuplicates(x,9)


不用说,还有其他有效的方法,比如哈希,可以用来降低代码的时间复杂度

只要头部与值匹配,就要继续移除头部。因此,将
if
替换为
while

Node n = head;
while (n != null && n.data == d) {
    n = n.next; 
}
head = n;
你还有其他问题。例如,当
n.next
为空时,此行将引发空指针异常:

if(n.next == null && n.next.data == d) {
修复您的while循环:

while (n.next != null) {
    if (n.next.data == d) {
        n.next = n.next.next;
    } else {
        n = n.next;
    }
}
最后,您选择的方法名称非常容易引起误解。 “删除重复项”建议删除所有重复项, 例如:

只调用此方法
delete
是有意义的

把它放在一起 应用上述修正后,该方法变为:

Node delete(Node head, int d) {
    Node n = head;

    // skip consecutive d values at head
    while (n != null && n.data == d) {
        n = n.next; 
    }
    head = n;

    // skip d values
    while (n.next != null) {
        if (n.next.data == d) {
            n.next = n.next.next;
        } else {
            n = n.next;
        }
    }

    return head;
}

通过运行代码进行验证。您的代码应该如下所示:

x.deleteDuplicates(x, 9).print();
那么删除方法应该是:

Node deleteDuplicates(Node head, int d) {
    Node nextNode=head;
    if(head.data == d) {
        if(head.next==null) {
            return null;
        }
         return deleteDuplicates(head.next, d);
    }
    Node previous=head;
    while(nextNode.next != null) {
        nextNode=nextNode.next;
        if(nextNode.data == d) {
            previous.next=nextNode.next;
        }
        previous=nextNode;
    }
    return head;
}
输出:

5
6
7
8
在“检查是否需要删除头部节点”中,将下一个节点作为头部节点。还可以检查是否要删除最后一个节点,然后将前一个节点设置为空

类似(未经测试的代码):

其思想是,对于每个元素,遍历列表的其余部分,并删除和复制当前元素

public void deleteDupes(Node head) {
  if (head == null || head.next == null) {
    return;
  }
  Node current = head;
  while (current != null) {
    Node runner = head;
    while (runner.next != null) {
      if (runner.next.val == current.val) {
        runner.next = runner.next.next;
      }
      else {
        runner = runner.next;
      }
    }
    current = current.next;
  }
}

这是家庭作业吗?如果不是,您可以将列表转换为
哈希集
,以删除重复项。我怀疑这是为了家庭作业,否则你就不能使用
Node
。。。如果它是为了家庭作业,那么它可能与
deleteDuplicates()
中的第一个
If
语句有关,如果值相等,它看起来只是移动到下一个节点,这是重复的条件?认同,平等,另一个?还是不起作用。。。您需要实现散列码和相等,然后下一部分将不同,因此无法工作。仅供参考,不要让投票人失望,所以我不能帮你解决这个问题@StackFlow我用一个初始LinkedList测试了我的解决方案,它运行良好。我认为这些元素需要实现可比性,我将尝试以某种方式将其添加到我的答案中。下一票没有问题,如果OP的代码是用于生产而不是用于练习,那很遗憾,因为他基本上是重新发明了轮子。它将适用于Integer,因为所有实现都适用于Integer。尝试一下您编写的类,然后尝试一下,您将看到我说的内容。@Stackflowd您是对的,HashSet.add()基于.equals而不是.compareTo。我很确定有一个界面可以保证在一个集合中的可用性,所以可比性看起来是显而易见的选择,但遗憾的是我错了。你还记得.hashCode在哪里起作用吗?我在HashSet文档中找不到它。@StackFlowed nevermind,Object说HashMaps中使用了hashCode,它支持HashSet;我正在修正我的答案
public void deleteDupes(Node head) {
  if (head == null || head.next == null) {
    return;
  }
  Node current = head;
  while (current != null) {
    Node runner = head;
    while (runner.next != null) {
      if (runner.next.val == current.val) {
        runner.next = runner.next.next;
      }
      else {
        runner = runner.next;
      }
    }
    current = current.next;
  }
}