甚至在奇数元素之后对LinkedList进行排序

时间:2017-10-16 13:44:14

标签: java algorithm mergesort

我正在尝试解决这个问题:"在给定的链接列表中排列元素,使得所有偶数都放在奇数之后。元素的各个顺序应保持不变。"

这是我正在使用的代码:

class Node<T> {
    T data;
    Node<T> next;
    Node(T data) {
        this.data = data;
    }
}

这是主要逻辑:

static Node<Integer> sortOddEven(Node<Integer> head) {
    if(head == null || head.next == null) {
        return head;
    }

    Node<Integer> middle = getMiddle(head);
    Node<Integer> nextOfMiddle = middle.next;

    middle.next = null;

    Node<Integer> temp1 = sortOddEven(head);
    Node<Integer> temp2 = sortOddEven(nextOfMiddle);

    Node<Integer> sortedList = sortOddEvenMerger(temp1, temp2);
    return sortedList;
}

static Node<Integer> sortOddEvenMerger(Node<Integer> head1, Node<Integer> head2) {
    Node<Integer> head3 = null, tail3 = null;

    if(head1.data.intValue()%2 != 0) {
        head3 = head1;
        tail3 = head1;

        head1 = head1.next;
    } else {
        head3 = head2;
        tail3 = head2;

        head2 = head2.next;
    }

    while(head1 != null || head2 != null) {

        if(head1 == null) {
            tail3.next = head2;

            return head3;
        } else if(head2 == null){
            tail3.next = head1;

            return head3;
        }

        if(head1.data.intValue()%2 != 0) {
            tail3.next = head1;
            tail3 = tail3.next;

            head1 = head1.next;
        } else {
            tail3.next = head2;
            tail3 = tail3.next;

            head2 = head2.next;
        }

    }

    tail3.next = null;

    return head3;
}

基本上我已经稍微调整了MergeSort算法来解决这个问题,如果我遇到奇数元素,我先在sortOddEvenMerger方法中添加它们,然后在它们之后添加元素。但元素的相对顺序会发生变化。

  

示例:输入 - 1 4 5 2

     

预期产出 - 1 5 4 2

     

我的输出 - 1 5 2 4

如何更多调整以维持相对顺序?

2 个答案:

答案 0 :(得分:7)

你的方法不仅使问题比现在更困难,而且效率也更低,因为如果我正确理解它是O(nlgon)。这是因为您正在尝试实施mergesort算法,并对奇数(和偶数)元素进行排序,从而导致错误的结果。

一个简单的算法:

  • 制作两个最初为空的新列表(一个用于偶数元素的奇数列表)。

  • 遍历主列表并将奇数列表中找到的每个奇数元素和偶数列表中的每个偶数元素相加。对于遍历,O(n)为每个列表中的每次插入O(1)

  • 当主列表中没有任何元素时,你有两个奇数 - 甚至是具有正确顺序的元素的列表,所以只需链接它们以获得一个具有预期输出的列表 - 这一步也是O(1)! / p>

总复杂度:O(n)。(其中n是主列表的长度)。

答案 1 :(得分:0)

此问题的 Python 代码:

def evenAfterOdd(head):
    if head is None:
        return head
    end = head
    prev = None
    curr = head

    # Get pointer to last Node
    while (end.next != None):
        end = end.next

    new_end = end

    # Consider all even nodes before getting first odd node
    while (curr.data % 2 != 1 and curr != end):
        new_end.next = curr
        curr = curr.next
        new_end.next.next = None
        new_end = new_end.next

    # do following steps only if there is an odd node
    if (curr.data % 2 == 1):

        head = curr

        # now curr points to first odd node
        while (curr != end):

            if (curr.data % 2 == 1):

                prev = curr
                curr = curr.next

            else:

                # Break the link between prev and curr
                prev.next = curr.next

                # Make next of curr as None
                curr.next = None

                # Move curr to odd
                new_end.next = curr

                # Make curr as new odd of list
                new_end = curr

                # Update curr pointer
                curr = prev.next

    # We have to set prev before executing rest of this code
    else:
        prev = curr

    if (new_end != end and end.data % 2 != 1):
        prev.next = end.next
        end.next = None
        new_end.next = end
    return head