Java程序合并两个排序列表(就地)
给定两个排序列表,将它们合并以产生一个组合排序列表(不使用额外空间)。
例子:
Input: head1: 5->7->9
head2: 4->6->8
Output: 4->5->6->7->8->9
Explanation: The output list is in sorted order.
Input: head1: 1->3->5->7
head2: 2->4
Output: 1->2->3->4->5->7
Explanation: The output list is in sorted order.
下面的帖子中有不同的讨论不同的解决方案。
合并两个排序的链表
方法1(递归):
方法:给定链表已排序,可以形成递归解决方案。
- 比较两个链表的头部。
- 在两个头节点中找到较小的节点。当前元素将是两个头节点中较小的节点。
- 两个列表的其余元素将在此之后出现。
- 现在运行一个带有参数的递归函数、较小元素的下一个节点和另一个头。
- 递归函数将返回与排序元素的其余部分链接的下一个较小元素。现在将当前元素的下一个指向该元素,即curr_ele->next=recursivefunction()
- 处理一些极端情况。
- 如果两个头都为 NULL,则返回 null。
- 如果一个头为空,则返回另一个。
Java
// Java program to merge two sorted
// linked lists in-place.
class GFG
{
static class Node
{
int data;
Node next;
};
// Function to create newNode in
// a linkedlist
static Node newNode(int key)
{
Node temp = new Node();
temp.data = key;
temp.next = null;
return temp;
}
// A utility function to print
// linked list
static void printList(Node node)
{
while (node != null)
{
System.out.printf("%d ",
node.data);
node = node.next;
}
}
// Merges two given lists in-place.
// This function mainly compares head
// nodes and calls mergeUtil()
static Node merge(Node h1, Node h2)
{
if (h1 == null)
return h2;
if (h2 == null)
return h1;
// start with the linked list
// whose head data is the least
if (h1.data < h2.data)
{
h1.next = merge(h1.next, h2);
return h1;
}
else
{
h2.next = merge(h1, h2.next);
return h2;
}
}
// Driver program
public static void main(String args[])
{
Node head1 = newNode(1);
head1.next = newNode(3);
head1.next.next = newNode(5);
// 1.3.5 LinkedList created
Node head2 = newNode(0);
head2.next = newNode(2);
head2.next.next = newNode(4);
// 0.2.4 LinkedList created
Node mergedhead = merge(head1, head2);
printList(mergedhead);
}
}
// This code is contributed by Arnab Kundu
Java
// Java program to merge two sorted
// linked lists in-place.
class GfG
{
static class Node
{
int data;
Node next;
}
// Function to create newNode in
// a linkedlist
static Node newNode(int key)
{
Node temp = new Node();
temp.data = key;
temp.next = null;
return temp;
}
// A utility function to print
// linked list
static void printList(Node node)
{
while (node != null)
{
System.out.print(node.data +
" ");
node = node.next;
}
}
// Merges two lists with headers as
// h1 and h2. It assumes that h1's
// data is smaller than or equal to
// h2's data.
static Node mergeUtil(Node h1, Node h2)
{
// if only one node in first list
// simply point its head to second
// list
if (h1.next == null)
{
h1.next = h2;
return h1;
}
// Initialize current and next
// pointers of both lists
Node curr1 = h1, next1 = h1.next;
Node curr2 = h2, next2 = h2.next;
while (next1 != null &&
curr2 != null)
{
// if curr2 lies in between curr1
// and next1 then do curr1->curr2->next1
if ((curr2.data) >= (curr1.data) &&
(curr2.data) <= (next1.data))
{
next2 = curr2.next;
curr1.next = curr2;
curr2.next = next1;
// now let curr1 and curr2 to point
// to their immediate next pointers
curr1 = curr2;
curr2 = next2;
}
else
{
// if more nodes in first list
if (next1.next != null)
{
next1 = next1.next;
curr1 = curr1.next;
}
// else point the last node of
// first list to the remaining
// nodes of second list
else
{
next1.next = curr2;
return h1;
}
}
}
return h1;
}
// Merges two given lists in-place.
// This function mainly compares head
// nodes and calls mergeUtil()
static Node merge(Node h1, Node h2)
{
if (h1 == null)
return h2;
if (h2 == null)
return h1;
// start with the linked list
// whose head data is the least
if (h1.data < h2.data)
return mergeUtil(h1, h2);
else
return mergeUtil(h2, h1);
}
// Driver code
public static void main(String[] args)
{
Node head1 = newNode(1);
head1.next = newNode(3);
head1.next.next = newNode(5);
// 1->3->5 LinkedList created
Node head2 = newNode(0);
head2.next = newNode(2);
head2.next.next = newNode(4);
// 0->2->4 LinkedList created
Node mergedhead = merge(head1,
head2);
printList(mergedhead);
}
}
// This code is contributed by prerna saini
输出:
0 1 2 3 4 5
复杂性分析:
- 时间复杂度: O(n)。
只需要遍历一次链表。 - 辅助空间: O(n)。
如果考虑递归堆栈空间。
方法2(迭代):
方法:这种方法与上述递归方法非常相似。
- 从头到尾遍历列表。
- 如果第二个列表的头节点位于第一个列表的两个节点之间,则将其插入其中并使第二个列表的下一个节点成为头。继续此操作,直到两个列表中都没有节点,即遍历两个列表。
- 如果第一个列表在遍历时到达末尾,则将下一个节点指向第二个列表的头部。
注意:比较两个列表,其中头部值较小的列表是第一个列表。
Java
// Java program to merge two sorted
// linked lists in-place.
class GfG
{
static class Node
{
int data;
Node next;
}
// Function to create newNode in
// a linkedlist
static Node newNode(int key)
{
Node temp = new Node();
temp.data = key;
temp.next = null;
return temp;
}
// A utility function to print
// linked list
static void printList(Node node)
{
while (node != null)
{
System.out.print(node.data +
" ");
node = node.next;
}
}
// Merges two lists with headers as
// h1 and h2. It assumes that h1's
// data is smaller than or equal to
// h2's data.
static Node mergeUtil(Node h1, Node h2)
{
// if only one node in first list
// simply point its head to second
// list
if (h1.next == null)
{
h1.next = h2;
return h1;
}
// Initialize current and next
// pointers of both lists
Node curr1 = h1, next1 = h1.next;
Node curr2 = h2, next2 = h2.next;
while (next1 != null &&
curr2 != null)
{
// if curr2 lies in between curr1
// and next1 then do curr1->curr2->next1
if ((curr2.data) >= (curr1.data) &&
(curr2.data) <= (next1.data))
{
next2 = curr2.next;
curr1.next = curr2;
curr2.next = next1;
// now let curr1 and curr2 to point
// to their immediate next pointers
curr1 = curr2;
curr2 = next2;
}
else
{
// if more nodes in first list
if (next1.next != null)
{
next1 = next1.next;
curr1 = curr1.next;
}
// else point the last node of
// first list to the remaining
// nodes of second list
else
{
next1.next = curr2;
return h1;
}
}
}
return h1;
}
// Merges two given lists in-place.
// This function mainly compares head
// nodes and calls mergeUtil()
static Node merge(Node h1, Node h2)
{
if (h1 == null)
return h2;
if (h2 == null)
return h1;
// start with the linked list
// whose head data is the least
if (h1.data < h2.data)
return mergeUtil(h1, h2);
else
return mergeUtil(h2, h1);
}
// Driver code
public static void main(String[] args)
{
Node head1 = newNode(1);
head1.next = newNode(3);
head1.next.next = newNode(5);
// 1->3->5 LinkedList created
Node head2 = newNode(0);
head2.next = newNode(2);
head2.next.next = newNode(4);
// 0->2->4 LinkedList created
Node mergedhead = merge(head1,
head2);
printList(mergedhead);
}
}
// This code is contributed by prerna saini
输出:
0 1 2 3 4 5
复杂性分析:
- 时间复杂度: O(n)。
因为只需要遍历一次链表。 - 辅助空间: O(1)。
因为不需要空间。
有关更多详细信息,请参阅有关合并两个排序列表(就地)的完整文章!