【问题标题】:How to merge two ordered singly linked list into one ordered list如何将两个有序单链表合并为一个有序表
【发布时间】:2017-03-27 09:39:42
【问题描述】:

我正在尝试合并两个有序的单链表。我尝试搜索问题出在哪里,但找不到答案。输出不是我所期望的。 输出如下

class Test
{
Node head;  // head of list
class Node
{
    int data;
    Node next;
    Node(int d){
        data = d; 
        next = null; 
    }
}

void sortedInsert(Node newNode)
{
     Node current;
     if (head == null || head.data >= newNode.data)
     {
        newNode.next = head;
        head = newNode;
     }
     else {
        current = head;
        while (current.next != null && current.next.data < newNode.data)
            current = current.next;

        newNode.next = current.next;
        current.next = newNode;
     }
 }
 Node newNode(int data)
{
   Node x = new Node(data);
   return x;
}

 /* Function to print linked list */
 void printList()
 {
     Node temp = head;
     while (temp != null)
     {
        System.out.print(temp.data+"-> ");
        temp = temp.next;
     }
     System.out.print("null\n");
 }

 Node mergeLists(Node list1, Node list2) {
    Node result;
    if (list1 == null) return list2;
    if (list2 == null) return list1;
    if (list1.data < list2.data) {
        result = list1;
        result.next = mergeLists(list1.next, list2);
    } else {
        result = list2;
        result.next = mergeLists(list2.next, list1);
    }
    return result;
}

 /* Drier function to test above methods */
 public static void main(String args[])
 {
     Test oneList = new Test();
     Test twoList = new Test();
     Test joinList = new Test();
     Node l1,l2,join;

     //First linked list
     l1 = oneList.newNode(11);
     oneList.sortedInsert(l1);
     l1 = oneList.newNode(13);
     oneList.sortedInsert(l1);
     l1 = oneList.newNode(12);
     oneList.sortedInsert(l1);
     l1 = oneList.newNode(17);
     oneList.sortedInsert(l1);
     l1 = oneList.newNode(15);
     oneList.sortedInsert(l1);
     l1 = oneList.newNode(19);
     oneList.sortedInsert(l1);
     System.out.println("First List");
     oneList.printList();

     //Second Linked List
     l2 = twoList.newNode(1);
     twoList.sortedInsert(l2);
     l2 = twoList.newNode(5);
     twoList.sortedInsert(l2);
     l2 = twoList.newNode(3);
     twoList.sortedInsert(l2);
     l2 = twoList.newNode(7);
     twoList.sortedInsert(l2);
     l2 = twoList.newNode(4);
     twoList.sortedInsert(l2);
     l2 = twoList.newNode(19);
     twoList.sortedInsert(l2);
     System.out.println("Created Second Linked List");
     twoList.printList();

     join=joinList.mergeLists(l1,l2);
     System.out.println("Merge");
     joinList.sortedInsert(join);
     joinList.printList();
 }
 }

输出:

第一个列表

11-> 12-> 13-> 15-> 17-> 19-> 空

创建第二个链表

1-> 3-> 4-> 5-> 7-> 19-> 空

合并

19-> 空

【问题讨论】:

  • 欢迎来到 Stack Overflow!看来您需要学习使用调试器。请帮助自己一些complementary debugging techniques。如果之后仍有问题,请随时回来提供更多详细信息。
  • 不应该合并是 joinList.head = mergLists(oneList.head, twoList.head); ?
  • 你想将两个排序的链表合并为一个吗?

标签: java sorting data-structures linked-list singly-linked-list


【解决方案1】:

主要方法有一个问题

 oneList.sortedInsert(l1);
 l1 = oneList.newNode(15);
 oneList.sortedInsert(l1);
 l1 = oneList.newNode(19);

l1 是列表 19 -> NULL 和 l2 19 -> NULL 相同。所以合并似乎是正确的,问题是你用最后一个元素而不是第一个元素覆盖 l1l2。我希望这会有所帮助。

【讨论】:

  • 没有,即使我改变了 oneList.sortedInsert(l1); l1 = oneList.newNode(15); oneList.sortedInsert(l1); l1 = oneList.newNode(21);那么现在的答案是 21->null。我希望列表都被合并和排序。但我做不到。
  • 你可以尝试删除赋值 l1 = in all l1 = oneList.newNode(x);除了第一个。
  • 不,那是行不通的。有没有其他方法可以告诉你?
  • 在 Test 中有一个 getHead() 方法,它返回 head 或者对于第一个 newNode() 有一个不同的变量,即 head1 = new Node(5); l1 = 新节点(6)...
【解决方案2】:

您不希望递归地执行此操作,因为如果列表足够大,您将溢出堆栈。合并两个列表是一个简单的迭代操作。基本思路是:

if (list1 == null) return list2;
if (list2 == null) return list1;

Node head = null;
Node l1 = list1;
Node l2 = list2;

if (l1.data < l2.data)
{
    head = l1;
    l1 = l1.next;
}
else
{
    head = l2;
    l2 = l2.next;
}

Node current = head;
// while not at end of either list
while (l1 != null && l2 != null)
{
    if (l1.data < l2.data)
    {
        current.next = l1;
        l1 = l1.next;
    }
    else
    {
        current.next = l2;
        l2 = l2.next;
    }
    current = current.next;
    current.next = null;
}
// at this point, you are at the end of one or both of the lists
// Pick up the potential remainder from the list that's not at the end.
// Note that only one of these loops will be entered.
while (l1 != null)
{
    current.next = l1;
    current = current.next;
    current.next = null;
    l1 = l1.next;
}
while (l2 != null)
{
    current.next = l2;
    current = current.next;
    current.next = null;
    l2 = l2.next;
}
return head;

这是简单的详细解决方案。您可以通过创建一个将节点附加到新列表的方法来稍微减少代码量,但逻辑是相同的。

【讨论】:

    猜你喜欢
    • 2015-04-28
    • 1970-01-01
    • 2019-08-19
    • 2014-04-25
    • 2017-08-23
    • 1970-01-01
    • 2023-03-25
    • 2020-10-09
    • 1970-01-01
    相关资源
    最近更新 更多