合并两个不等长度的已排序链表

时间:2013-07-19 11:46:46

标签: java algorithm data-structures linked-list mergesort

我正在尝试合并两个已排序的链表。

代码段不适用于以下两个列表:

List 1 : 1->3->5->7->9->null
List 2 : 2->4->6->8->10->null

Expected List : 1->2->3->4->5->6->7->8->9->10->null

但是以下程序的输出结果是这样的:

Output :  1->2->3->4->5->6->7->8->9->null // element 10 is missing.

我错过了什么吗?现场演示:http://ideone.com/O7MBlo

class Node {

    Node next;
    int value;

    Node(int val) {
        this.value = val;
        this.next = null;
    }

    @Override
    public String toString() {
        Node cur = this;
        String str = "";

        while(cur != null) {
            str += cur.value+"->";
            cur = cur.next;
        }

        return str;
    }
}

class MergeLL {

    public static Node merge(Node n1, Node n2) {

        Node result = null;

        if(n1 != null && n2 != null) {
            if(n1.value < n2.value) {
                result = n1;
                result.next = merge(n1.next, n2);
            } else {
                result = n2;
                result.next = merge(n1, n2.next);
            }
        }
        return result;
    }

    public static void main(String[] args) {
        Node n1 = new Node(1);
        Node n3 = new Node(3);
        Node n5 = new Node(5);
        Node n7 = new Node(7);
        Node n9 = new Node(9);

        n1.next = n3;
        n3.next = n5;
        n5.next = n7;
        n7.next = n9;
        n9.next = null;

        Node n2 = new Node(2);
        Node n4 = new Node(4);
        Node n6 = new Node(6);
        Node n8 = new Node(8);
        Node n10 = new Node(10);

        n2.next = n4;
        n4.next = n6;
        n6.next = n8;
        n8.next = n10;
        n10.next = null;

        System.out.println("Merge : " + merge(n1, n2));
    }
}

8 个答案:

答案 0 :(得分:7)

n1n2更早耗尽时,您需要再添加两个条件。因此,您的条件 - n1 != null && n2 != null仅适用于列表大小相同的情况。

只需添加以下两个条件的代码,之后如果:

if(n1 != null && n2 != null) {
        if(n1.value < n2.value) {
            result = n1;
            result.next = merge(n1.next, n2);
        } else {
            result = n2;
            result.next = merge(n1, n2.next);
        }

} else if (n1 != null) {  
    result = n1;  // Add all the elements of `n1` to `result`
} else if (n2 != null) {
    result = n2;  // Add all the elements of `n2` to `result`
}

实际上,你不需要在那里建立一个新的result列表。您可以简单地扩展其中一个传递的节点。

您可以按以下方式修改方法:

public static Node merge(Node n1, Node n2) {
    if (n1 == null) return n2;
    if (n2 == null) return n1;

    if (n1.value < n2.value) {
        n1.next = merge(n1.next, n2);
        return n1;
    } else {
        n2.next = merge(n2.next, n1);
        return n2;
    }
}

答案 1 :(得分:2)

递归算法有一个基本条件。所以你的基本条件是:

  • 空列表n1和n2
  • n1为空,n2为空。
  • n2空,n1为空。

将您的基本条件2和3处理为:

在条件2中,基本条件为n2为空,因此我们将返回n1:

else if(n1!=null ){
        result=n1;
    }

在条件3中,基本条件为n1为空,因此我们将返回n2:

else if(n2!=null ){
        result=n2;
    }

因此问题是在算法中设计你的基本条件!!

所以试试这个,肯定有效

public static Node merge(Node n1, Node n2) {
    Node result = null;

    if(n1 != null && n2 != null) {
        if(n1.value < n2.value) {
            result = n1;
            result.next = merge(n1.next, n2);
        } else {
            result = n2;
            result.next = merge(n1, n2.next);
        }

    }
    else if(n1!=null ){
        result=n1;
    }
    else if(n2!=null){
        result=n2;
    }
    return result;
}
祝你好运!!

修改This链接可以帮助您设计递归算法。

答案 2 :(得分:1)

if(n1 != null && n2 != null) {

当其中一个列表为空但另一个列表不为时会发生什么?

返回null。但它应该返回非空的列表。

可能的解决方案就像;

if(n1 == null)
  return n2;
if(n2 == null)
  return n1;

if(n1.value < n2.value) {
  result = n1;
  result.next = merge(n1.next, n2);
  } else {
  result = n2;
  result.next = merge(n1, n2.next);
}

答案 3 :(得分:1)

合并两个排序链表的解决方案: https://leetcode.com/problems/merge-two-sorted-lists/

虽然循环将执行到列表之一完成,但另一个列表的剩余数据将稍后附加到while循环之外。

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
        public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
            ListNode dummy = new ListNode(0);
            ListNode head = dummy;

            while(l1 != null && l2 != null) {
                if(l1.val <= l2.val) {
                    dummy.next = l1;
                    l1 = l1.next;
                }else{
                    dummy.next = l2;
                    l2 = l2.next;
                }

                dummy = dummy.next;
            }

            if(l1 != null) {
                dummy.next = l1;
            }else {
                dummy.next = l2;
            }

            return head.next;
        }
    }

答案 4 :(得分:0)

它也可以进行优化。只是为了理解

public static Node merge(Node n1, Node n2) {

        Node result = null;

        if(n1 != null && n2 != null) {
            if(n1.value < n2.value) {
                result = n1;
                result.next = merge(n1.next, n2);
            } else {
                result = n2;
                result.next = merge(n1, n2.next);
            }
        }
        else if(n1 != null) {
            result = n1;
            result.next = merge(n1.next, n2);
        }
        else if(n2 != null) {
            result = n2;
            result.next = merge(n1, n2.next);
        }
        return result;
    }

答案 5 :(得分:0)

package test;

import java.util.*;

public class TestMergeLists<T extends Comparable<? super T>>
{
    static <T extends Comparable<? super T>> List<T> merge(List<T> a,List<T>b)
    {
        Collections.sort(a);
        Collections.sort(b);
        List<T> result = new ArrayList<T>();
        int i = 0;
        int j = 0;

        for (;;)
        {
            T a1 = a.get(i);
            T b1 = b.get(j);
            if (a1.compareTo(b1) > 0)
            {
                result.add(b1);
                j++;
                if (j == b.size())// no more
                {
                    if (i < a.size() - 1)
                        result.addAll(a.subList(i + 1, a.size()));
                    break;
                }
            } else if (a1.compareTo(b1) == 0)
            {
                result.add(a1);
                result.add(b1);
                i++;
                if (i == a.size())
                {
                    if (j < b.size() - 1)
                        result.addAll(b.subList(j + 1, b.size()));
                    break;
                }
                j++;
                if (j == b.size())// no more
                {
                    if (i < a.size() - 1)
                        result.addAll(a.subList(i + 1, a.size()));
                    break;
                }
            } else
            {
                result.add(a1);
                i++;
                if (i == a.size())// no more
                {
                    if (j < b.size() - 1)
                        result.addAll(b.subList(j + 1, b.size()));
                    break;
                }
            }
        }
        return result;
    }
    public static void main(String args[])
    {
        List<String> a = new ArrayList<String>();
        a.addAll(Arrays.asList("the statement you found confusing is how MergeSort merges two ".split(" ")));
        List<String> b = new ArrayList<String>();
        b.addAll(Arrays.asList("then increment the current index for ".split(" ")));
        List<String> result = merge(a,b);
        System.out.println(result);
    }
}

答案 6 :(得分:0)

这是用于合并两个已排序的链接列表的简单和迭代(非递归)代码:

import java.util.*;
class Node
{
 public int data;
 public Node next;
 Node(int x)
 {
     data=x;
     next=null;
 }
}
public class Test {
        public static Node merge(Node a, Node b)
        {
          Node res=null; 
          Node first=null;
          if(a.data < b.data)
              {
                  res=a;
                  first=a;
                  a=a.next;
              }
              else
              {   
                  first=b;
                  res=b;
                  b=b.next;
              }

          while(a!=null && b!=null)
          {
              if(a.data < b.data)
              { 
                  res.next=a;
                  res=res.next;
                  a=a.next;
              }
              else
              {  
                  res.next=b;
                  res=res.next;
                  b=b.next;
              }   
          } 
          if(a!=null)
          {
              res.next=a;
          }
          else if(b!=null)
          {
              res.next=b;
          }

          return first;
        }

        public static void display(Node first)
        {
            while(first!=null)
            {
                System.out.print(first.data+" ");
                first=first.next;
            }
        }
        public static void main(String[] args)
        {
            Node n1=new Node(4);
            Node n2=new Node(5);
            Node n3=new Node(7);
            Node n4=new Node(10);
            n1.next=n2;
            n2.next=n3;
            n3.next=n4;
            n4.next=null;

            Node n5=new Node(3);
            Node n6=new Node(6);
            Node n7=new Node(9);
            Node n8=new Node(15);
            n5.next=n6;
            n6.next=n7;
            n7.next=n8;
            n8.next=null;

            Node f = merge(n1,n5);
            display(f);
        }
}

答案 7 :(得分:0)

合并两个排序列表| Leetcode问题| Javascript解决方案

fun updateVideoPreview(holder: SurfaceHolder) {
    if (SipManager.currentCall != null &&
            SipManager.currentCall?.mVideoPreview != null) {
        if (videoPreviewActive) {
            val vidWH = VideoWindowHandle()
            vidWH.handle?.setWindow(holder.surface)
            val vidPrevParam = VideoPreviewOpParam()
            vidPrevParam.window = vidWH
            try {
                SipManager.currentCall?.mVideoPreview?.start(vidPrevParam)
            } catch (e: Exception) {
                println(e)
            }
        } else {
            try {
                SipManager.currentCall?.mVideoPreview?.stop()
            } catch (e: Exception) {
                println(e)
            }
        }
    }
}
相关问题