簡體   English   中英

如何在Java中改進合並兩個排序鏈接列表的代碼

[英]How to improve my code of Merge two sorted link list in Java

我通過電子郵件收到了Microsoft的一次面試問題,這很簡單,只需合並兩個排序的鏈表,並確保沒有相同的數據。

我用Java實現了它:

https://gist.github.com/cb4cd94f74cff1d2bd03

起初,我想使用遞歸,但是當列表太大時,我認為效率不高。 所以我用,而代替。

但是當我發回它時,再也沒有響應了,所以我想知道我的代碼中有什么錯誤嗎? 我應該如何改善呢?

謝謝 !

您正在檢查列表之一是否為null然后拋出RuntimeException嗎? 我認為,如果其中一個列表為null ,而另一個列表不是,則可以只返回第二個。 我想念什么嗎? 無論如何,如果輸入不符合您的預期,則沒有理由拋出RuntimeException ,則InvalidArgumentException更合適。

if (head1 == null || head2 == null) {
        throw new RuntimeException(
                "Unavaliable source data sets, please make sure both of the two lists are not null");
    }

而且,您的代碼不是最佳的。 我會講一些更簡潔的方法:(請注意使用訪問器方法,而不是直接訪問Node類成員-由於破壞了封裝,它被認為是不好的)

Node MergeLists(Node list1, Node list2) {
    if (list1 == null) {
       return list2;
    } 
    if (list2 == null) {
        return list1;
    }  

    if (list1.getData() < list2.getData()) {
        list1.setNext(MergeLists(list1.getNext(), list2));
        return list1;
    } else {
        if (list1.getData() != list2.getData()) {
            list2.setNext(mergeLists(list2.getNext(), list1));
            return list2;
        }

        Node tail = mergeLists(list2.getNext(), list1.getNext());
        tail = (tail == null) ? null : tail.getNext();

        list2.setNext(tail);
        return list2;
    }
}

您可以改善算法以解決如下列表:

 1 -> 4 -> 6 -> 8  -> 12
 2 -> 3 -> 9 -> 10 -> 19

與您的算法:

1:    1 -> 2 -> 4 -> 6 -> 8 -> 12        Node1: 1, Node2: 2
2:    1 -> 2 -> 3 -> 4 -> 6 -> 8 -> 12   Node1: 2, Node2: 3
3:    1 -> 2 -> 3 -> 4 -> 6 -> 8 -> 12   Node1: 3, Node2: 9  
...

使用優化的算法,您會看到2-> 3會適合1-> 4,並且將1指向2並將3指向4。這組指令使得它:

 ...
 tmp = head2.next;
 head2.next = head1.next;
 head1.next = head2;
 head2 = tmp;
 head1 = head1.next;
 ...

請參見設置head1.next = head2然后兩行設置head1.next = head2 head1 = head1.next

而且,很難理解並試圖確定節點之間正在發生什么。 您的評論沒有用。 也許類似//swap the nodes

您的while循環可以使用退出條件。 多個出口點不是很好的樣式。 無限循環是一個很大的問題,它們使理解/繪制代碼變得更加困難。

希望這可以幫助。

編輯:這是我想出的。

public static Node merge(Node node1, Node node2){
    //store head to be returned (the smallest)
    Node masterHead = node1.value > node2.value? node2 : node1;
    //put smaller elements at the beginning
    while(node1 != null && node2.next != null && node1.value > node2.value)
    {   
        Node nextInList2 = node2.next;
        node2.next = node1;
        node1 = node2;
        node2 = nextInList2;
    }
    //merging loop
    while(node1.next != null && node2 != null){
        if(node1.next.value > node2.value)
        {
            //insert node(s) into the array
            Node higherNode = node1.next;
            node1.next = node2;
            //advance until every node being inserted is less that the next
            while(node2.next != null && higherNode.value > node2.next.value){
                node2 = node2.next;
            }
            //point back into the list
            Node nextInList2 = node2.next;
            node2.next = higherNode;
            node2= nextInList2;
        }
        node1 = node1.next;
    }
    if(node1.next == null)
        node1.next = node2;
    return masterHead;
}

我沒有測試空參數,只是因為它被假定為/我沒有把它變成微軟。

這是一個解決方案

Public static void merge(Node first, Node second){
    if(first==null) return second;
    if(second==null) return first;

    if(first.data<second.data){
        first.next = merge(first.next, second);
        return first;
    }else{
        second.next = merge(second.next, first);
        return second;
    }
}

該問題由Stefan Haustein在另一個線程中解決了!

訪談:合並兩個排序的單鏈接列表

public static Node merge(Node list1, Node list2) {
    if (list1 == null)
        return list2;
    if (list2 == null)
        return list1;

    Node head;
    if (list1.data < list2.data) {
        head = list1;
    } else {
        head = list2;
        list2 = list1;
        list1 = head;
    }
    while (list1.next != null && list2 != null) {
        if (list1.next.data <= list2.data) {
            list1 = list1.next;
        } else {
            Node tmp = list1.next;
            list1.next = list2;
            list2 = tmp;
        }
    }
    if (list1.next == null)
        list1.next = list2;
    return head;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM