简体   繁体   English

从链表中删除偶数在尾节点上不起作用?

[英]Removing even numbers from a linked list not working at the tail node?

void deleteEven() {
        boolean con = false;
        Node add;
        Node move;
        move = head;
        if (move.data % 2 == 0) {
            head = move.next;
            con = true;
        }
        add = move;
        move = move.next;
        while (move != null) {
            if (move.data % 2 == 0 ) {
                add.next = move.next;
                con = true;
            }
            add = move;
            move = move.next;
        }
        if (!con)
            System.out.println("No even numbers in list");
    }

It works for every node except the tail. 它适用于除尾部以外的所有节点。 if linked list is [5,4,3,2,2] the result is [5,3,2] How to fix that? 如果链接列表为[5,4,3,2,2],则结果为[5,3,2]如何解决?

The problem is not with the tail node. 问题不在于尾节点。 The problem is with two even nodes in a row irrespective of where they are in the list. 问题在于行中有两个偶数节点,无论它们在列表中的位置如何。 When the current node is even you are moving your pointer to the previous node ( add ) to the current node even though you have just removed it. 当当前节点是偶数时,即使您刚刚删除它,您也将指针移到当前节点的前一个节点( add )。 For the second even node your add.next = move.next statement changes next for the node you have just removed. 对于第二个偶数节点,您的add.next = move.next语句next针对刚删除的节点更改。

The simplest solution is to only move add if the node is not even: 最简单的解决方案是仅在节点不平时才移动add

if (move.data % 2 == 1) {
    add.next = move.next;
    con = true;
} else {
    add = move.next;
}

You could simplify your code quite a bit by getting rid of add altogether and just looking one node ahead of move : 您可以通过完全放弃add而仅在move之前查找一个节点,就可以大大简化代码:

while (move.next != null) {
    if (move.next.data % 2 == 0) {
        move.next = move.next.next;
        con = true;
    } else {
        move = move.next;
    }
}

And a programming tip for you: have several test cases before trying to diagnose a problem. 为您提供编程技巧:在尝试诊断问题之前,先要有几个测试用例。 I have found it's very easy to jump to an incorrect conclusion based on a small number of test cases and often expanding the range will make the problem clearer. 我发现根据少量的测试用例很容易得出错误的结论,并且经常扩大范围会使问题更清楚。 That is one of the (many) reasons that test driven development works as well as it does. 这就是测试驱动的开发效果很好的原因之一。

Let's create service Node for attaching other nodes. 让我们创建用于连接其他节点的服务节点。

Then loop through the list and copy the references in a new list (new Node are not created): 然后遍历列表,并将引用复制到新列表中(未创建新节点):

void deleteEven() {
    Node tmpHead = new Node(0, null);
    Node tmpCopy = tmpHead;
    Node tmp = head;
    while (tmp != null) {
        if (tmp.data % 2 == 1) {
            tmpCopy.next = tmp;
            tmpCopy = tmpCopy.next;
        }
        tmp = tmp.next;
    }
    tmpCopy.next = null;
    head = tmpHead.next;
}

Suppose what Node is: 假设节点是:

class Node {
    int data;
    Node next;

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

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

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