📜  Python程序合并两个排序列表(就地)

📅  最后修改于: 2022-05-13 01:56:56.316000             🧑  作者: Mango

Python程序合并两个排序列表(就地)

给定两个排序列表,将它们合并以产生一个组合排序列表(不使用额外空间)。
例子:

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(递归):

方法:给定链表已排序,可以形成递归解决方案。

  1. 比较两个链表的头部。
  2. 在两个头节点中找到较小的节点。当前元素将是两个头节点中较小的节点。
  3. 两个列表的其余元素将在此之后出现。
  4. 现在运行一个带有参数的递归函数、较小元素的下一个节点和另一个头。
  5. 递归函数将返回与排序元素的其余部分链接的下一个较小元素。现在将当前元素的下一个指向该元素,即curr_ele->next=recursivefunction()
  6. 处理一些极端情况。
    • 如果两个头都为 NULL,则返回 null。
    • 如果一个头为空,则返回另一个。
Python3
# Python3 program to merge two 
# sorted linked lists in-place.
import math
class Node: 
    def __init__(self, data): 
        self.data = data 
        self.next = None
  
# Function to create newNode in 
# a linkedlist
def newNode(key):
    temp = Node(key)
    temp.data = key
    temp.next = None
    return temp
  
# A utility function to print 
# linked list
def printList(node):
    while (node != None):
        print(node.data, 
              end = " ")
        node = node.next
  
# Merges two given lists in-place. 
# This function mainly compares 
# head nodes and calls mergeUtil()
def merge(h1, h2):
    if (h1 == None):
        return h2
    if (h2 == None):
        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 Code
if __name__=='__main__': 
    head1 = newNode(1)
    head1.next = newNode(3)
    head1.next.next = newNode(5)
  
    # 1.3.5 LinkedList created
    head2 = newNode(0)
    head2.next = newNode(2)
    head2.next.next = newNode(4)
  
    # 0.2.4 LinkedList created
    mergedhead = merge(head1, head2)
  
    printList(mergedhead)
  
# This code is contributed by Srathore


Python
# Python program to merge two 
# sorted linked lists in-place.
# Linked List node 
class Node: 
    def __init__(self, data): 
        self.data = data 
        self.next = None
  
# Function to create newNode in 
# a linkedlist
def newNode(key):
    temp = Node(0)
    temp.data = key
    temp.next = None
    return temp
  
# A utility function to print 
# linked list
def printList(node):
  
    while (node != None) :
        print( node.data, end =" ")
        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.
def mergeUtil(h1, h2):
  
    # if only one node in first list
    # simply point its head to second 
    # list
    if (h1.next == None) :
        h1.next = h2
        return h1
      
    # Initialize current and next 
    # pointers of both lists
    curr1 = h1
    next1 = h1.next
    curr2 = h2
    next2 = h2.next
  
    while (next1 != None and 
           curr2 != None): 
      
        # if curr2 lies in between curr1 
        # and next1 then do curr1.curr2.next1
        if ((curr2.data) >= (curr1.data) and
            (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) :
                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()
def merge(h1, h2):
  
    if (h1 == None):
        return h2
    if (h2 == None):
        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
head1 = newNode(1)
head1.next = newNode(3)
head1.next.next = newNode(5)
  
# 1.3.5 LinkedList created
head2 = newNode(0)
head2.next = newNode(2)
head2.next.next = newNode(4)
  
# 0.2.4 LinkedList created
mergedhead = merge(head1, head2)
  
printList(mergedhead)
# This code is contributed by Arnab Kundu


输出:

0 1 2 3 4 5 

复杂性分析:

  • 时间复杂度: O(n)。
    只需要遍历一次链表。
  • 辅助空间: O(n)。
    如果考虑递归堆栈空间。

方法2(迭代):

方法:这种方法与上述递归方法非常相似。

  1. 从头到尾遍历列表。
  2. 如果第二个列表的头节点位于第一个列表的两个节点之间,则将其插入其中并使第二个列表的下一个节点成为头。继续此操作,直到两个列表中都没有节点,即遍历两个列表。
  3. 如果第一个列表在遍历时到达末尾,则将下一个节点指向第二个列表的头部。

注意:比较两个列表,其中头部值较小的列表是第一个列表。

Python

# Python program to merge two 
# sorted linked lists in-place.
# Linked List node 
class Node: 
    def __init__(self, data): 
        self.data = data 
        self.next = None
  
# Function to create newNode in 
# a linkedlist
def newNode(key):
    temp = Node(0)
    temp.data = key
    temp.next = None
    return temp
  
# A utility function to print 
# linked list
def printList(node):
  
    while (node != None) :
        print( node.data, end =" ")
        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.
def mergeUtil(h1, h2):
  
    # if only one node in first list
    # simply point its head to second 
    # list
    if (h1.next == None) :
        h1.next = h2
        return h1
      
    # Initialize current and next 
    # pointers of both lists
    curr1 = h1
    next1 = h1.next
    curr2 = h2
    next2 = h2.next
  
    while (next1 != None and 
           curr2 != None): 
      
        # if curr2 lies in between curr1 
        # and next1 then do curr1.curr2.next1
        if ((curr2.data) >= (curr1.data) and
            (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) :
                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()
def merge(h1, h2):
  
    if (h1 == None):
        return h2
    if (h2 == None):
        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
head1 = newNode(1)
head1.next = newNode(3)
head1.next.next = newNode(5)
  
# 1.3.5 LinkedList created
head2 = newNode(0)
head2.next = newNode(2)
head2.next.next = newNode(4)
  
# 0.2.4 LinkedList created
mergedhead = merge(head1, head2)
  
printList(mergedhead)
# This code is contributed by Arnab Kundu

输出:

0 1 2 3 4 5 

复杂性分析:

  • 时间复杂度: O(n)。
    因为只需要遍历一次链表。
  • 辅助空间: O(1)。
    因为不需要空间。

有关更多详细信息,请参阅有关合并两个排序列表(就地)的完整文章!