无法从链接列表中删除元素?

时间:2018-10-10 21:15:14

标签: java data-structures linked-list traversal singly-linked-list

我只是在练习我的数据结构,并试图建立一种从单链列表中删除重复项的方法。这就是我所拥有的:

        void removeDup() {
            Node temp = head;
            Node cur = null;
            String s = "";

            while(temp!=null) {
                cur = temp;

                if(!s.contains(temp.data + "")) {
                    s += temp.data + "";
                }
                else {
                    cur.next = temp.next;
                }

                temp = temp.next;
            }
        }

执行此方法后,打印链接列表不会显示任何更改。我相信这是因为我没有正确地将上一个链接链接到当前链接的.next值,但是一切对我来说都是正确的。我调试了它,它似乎可以正确删除该节点,但是当我以后打印出链接列表时,仍然出现重复的节点。有建议吗?

3 个答案:

答案 0 :(得分:1)

代码是从https://www.geeksforgeeks.org/remove-duplicates-from-an-unsorted-linked-list/复制的:

方法1-蛮力,找到两个节点的所有对,看看它们是否具有相同的值,不确定是否调用System.gc()是个好主意:

/* Function to remove duplicates from an 
   unsorted linked list */
void remove_duplicates() { 
    Node ptr1 = null, ptr2 = null, dup = null; 
    ptr1 = head; 

    /* Pick elements one by one */
    while (ptr1 != null && ptr1.next != null) { 
        ptr2 = ptr1; 

        /* Compare the picked element with rest 
            of the elements */
        while (ptr2.next != null) { 

            /* If duplicate then delete it */
            if (ptr1.data == ptr2.next.data) { 

                /* sequence of steps is important here */
                dup = ptr2.next; 
                ptr2.next = ptr2.next.next; 
                System.gc(); 
            } else /* This is tricky */ { 
                ptr2 = ptr2.next; 
            } 
        } 
        ptr1 = ptr1.next; 
    } 
}

方法2-使用散列集帮助检测重复项,我个人更喜欢此方法:

 /* Function to remove duplicates from a 
       unsorted linked list */
    static void removeDuplicate(node head)  
    { 
        // Hash to store seen values, changed a little to compile for Java 8
        HashSet<Integer> hs = new HashSet<Integer>(); 

        /* Pick elements one by one */
        node current = head; 
        node prev = null; 
        while (current != null)  
        { 
            int curval = current.val; 

             // If current value is seen before 
            if (hs.contains(curval)) { 
                prev.next = current.next; 
            } else { 
                hs.add(curval); 
                prev = current; 
            } 
            current = current.next; 
        } 

    } 

答案 1 :(得分:0)

首先,我认为您选择将所有先前的内容保存在一个字符串中可能是一个坏主意。

例如,如果您用{x,y,xy}填充列表。第三项将被检测为重复项。 结合简单的替代方法。
将先前的值保存在某个collection /中,对于每个元素,检查是否还有其他等效项。 整理所有东西,然后检查人们的邻居。

您将cur设置为temp;在循环的顶部, 这样做cur.next = temp.next;以后什么都不做。 不要在循环的顶部将cur设置为temp,或者在之后将其更改。

答案 2 :(得分:0)

cur.next = temp.next不会更改任何内容。使用例如Java 8:

new LinkedList<>(Arrays.asList(1,2,1,3)).stream().distinct().collect(Collectors.toList());

new LinkedHashSet<>(new LinkedList<>(Arrays.asList(1,2,1,3)))

另请参阅https://www.geeksforgeeks.org/remove-duplicates-from-an-unsorted-linked-list