【问题标题】:Segregate even and odd nodes in a Linked List分离链表中的偶数和奇数节点
【发布时间】:2016-03-25 06:02:43
【问题描述】:

给定一个链表,我正在尝试将其划分为,以便偶数节点位于奇数节点之前。我的方法是创建两个不同的链表(偶数和奇数)来存储偶数和奇数。但是,当我想添加到偶数或奇数链表时遇到了问题(我在下面的代码中评论了我认为给我带来问题的部分)。谢谢!

public class SeperateOddEven {

    static Node head;
    static int count;

    public static class Node {
        int data;
        Node next;

        private Node(int data) {
            this.data = data;
            next = null;
            count++;
        }

    }


    public void seperate() {

        Node even = null;
        Node odd = null;
        Node temp;

        // go through each linked-list and place node in new list depending on whether they are even or odd
        while(head != null) {
            // if even, place in even linked-list
            if(head.data % 2 == 0) {
                temp = new Node(head.data);
                even = temp; // Problem here
                even = even.next; // and here 
            } else { // if head.data % 2 != 0
                temp = new Node(head.data);
                odd = temp;
                odd = odd.next;
            }
            head = head.next;
        }

        toString(even);
        //toString(odd);

    }

    public void toString(Node node) {
        while (node != null) {
            System.out.print(node.data + " ");
            node = node.next;
        }
    }

    public static void main(String[] args) {

        SeperateOddEven s = new SeperateOddEven();
        head = new Node(8);
        head.next = new Node(12);
        head.next.next = new Node(10);
        head.next.next.next = new Node(5);
        head.next.next.next.next = new Node(4);
        head.next.next.next.next.next = new Node(1);
        head.next.next.next.next.next.next = new Node(6);

        System.out.println("original list: ");
        s.toString(head);

        s.seperate();
    }
}

【问题讨论】:

标签: java linked-list


【解决方案1】:

我相信您准确地确定了问题所在。让我们逐行进行:

temp = new Node(head.data);

额外的temp 变量是不必要的,但很好。

even = temp;

然而,下一行出现了问题。您将even 分配给temp(使临时变得不必要)。如果某些内容以前存储在even 中,那么它现在会丢失给垃圾收集器,因为您现在没有对它的引用。 eventemp 现在都引用同一个 Node 对象。

我想你可能想做的是说even.next = temp。这将开始创建一个列表,但只有一个引用,您必须使用该引用指向列表的头部。每次您想追加到列表时,您都需要遍历它,直到找到结尾。如果您尝试将此单个引用指向列表的尾部,您将无法再回到头部,因为您的 Nodes 只有 next 引用,而不是 prev 引用(具有双向引用的列表称为双向链表)。

even = even.next;

因为even(和temp)都指向新创建的Node对象,所以even.next属性是null。所以当这条线执行时,even 现在指向空值。循环内的工作没有完成任何工作,因为您立即失去了对您创建的每个 Node 的引用。


试试这样的:

// Must keep track of head reference, because your Nodes can only go forward
Node evenHead = null;
Node evenTail = null;

Node oddHead = null;
Node oddTail = null;

while (head != null) {
    if(head.data % 2 == 0) {
        if (evenHead == null) {
            // The even list is empty, set the head and tail
            evenHead = new Node(head.data);
            evenTail = evenHead;
        } else {
            // Append to the end of the even list
            evenTail.next = new Node(head.data);
            evenTail = evenTail.next;
        }
    } else {
        // similar code for odd, consider creating a method to avoid repetition 
    }
}

【讨论】:

  • 这就像一个魅力。非常感谢您的帮助!
【解决方案2】:

你也可以试试这个:

while (head != null) {
            // if even, place in even linked-list
            temp = new Node(head.data);
            if (head.data % 2 == 0) {
                if(even == null) {
                    even = temp;
                } else{
                    Node insertionNode = even;
                    while(insertionNode.next != null) 
                        insertionNode = insertionNode.next;
                    insertionNode.next = temp;
                }


            } else { // if head.data % 2 != 0
                if(odd == null) {
                    odd = temp;
                } else{
                    Node insertionNode = odd;
                    while(insertionNode.next != null) 
                        insertionNode = insertionNode.next;
                    insertionNode.next = temp;
                }
            }
            head = head.next;
        }

【讨论】:

  • 由于我在上面的回答中解释的原因,此解决方案效率非常低。通过保留尾引用,您无需在每次插入时循环整个列表。这个解决方案是 O(n^2) 而不是 O(n)。
  • 嘿,非常感谢您的分享。我最终使用了 zposten 的方法,但你的方法也一样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-25
  • 1970-01-01
  • 2014-08-31
  • 1970-01-01
  • 2012-01-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多