将两个已排序的链接列表合并到python中的一个链接列表中

时间:2014-03-19 13:20:54

标签: python list linked-list sorted

这是我的代码:

def merge_lists(head1, head2):
    if head1 is None and head2 is None:
        return None
    if head1 is None:
        return head2
    if head2 is None:
        return head1
    if head1.value < head2.value:
        temp = head1
    else:
        temp = head2
    while head1 != None and head2 != None:
        if head1.value < head2.value:
            temp.next = head1
            head1 = head1.next
        else:
            temp.next = head2
            head2 = head2.next
    if head1 is None:
        temp.next = head2
    else:
        temp.next = head1
    return temp
    pass

这里的问题陷入无限循环。任何人都告诉我问题是什么

示例是:

 assert [] == merge_lists([],[])
 assert [1,2,3] == merge_lists([1,2,3], [])
 assert [1,2,3] == merge_lists([], [1,2,3])
 assert [1,1,2,2,3,3,4,5] == merge_lists([1,2,3], [1,2,3,4,5])

5 个答案:

答案 0 :(得分:10)

当前代码的问题在于,它会导致临时节点下一个的副作用它导航到当前节点的下一个节点。当前临时节点 当前节点时,这是有问题的。

也就是说,想象一下这个案例:

temp = N
temp.next = N  # which means N.next = N
N = N.next     # but from above N = (N.next = N) -> N = N

有一个更正版本,还有一些其他更新:

def merge_lists(head1, head2):
    if head1 is None:
        return head2
    if head2 is None:
        return head1

    # create dummy node to avoid additional checks in loop
    s = t = node() 
    while not (head1 is None or head2 is None):
        if head1.value < head2.value:
            # remember current low-node
            c = head1
            # follow ->next
            head1 = head1.next
        else:
            # remember current low-node
            c = head2
            # follow ->next
            head2 = head2.next

        # only mutate the node AFTER we have followed ->next
        t.next = c          
        # and make sure we also advance the temp
        t = t.next

    t.next = head1 or head2

    # return tail of dummy node
    return s.next

答案 1 :(得分:4)

用于合并两个已排序链接列表的递归算法

def merge_lists(h1, h2):
    if h1 is None:
        return h2
    if h2 is None:
        return h1

    if (h1.value < h2.value):
        h1.next = merge_lists(h1.next, h2)
        return h1
    else:
        h2.next = merge_lists(h2.next, h1)
        return h2

答案 2 :(得分:0)

完整代码:-

链表的每个节点的“节点”类的定义。

class Node:
    def __init__(self,data):
        self.data = data
        self.next = None

“链表”类的定义。

class linkedlist:
    def __init__(self):
        self.head = None

“合并”功能的定义。

参数“ ll1”和“ ll2”是两个链接列表的开头。

def merge_lists(ll1, ll2):
    if ll1 is None:
        return ll2
    if ll2 is None:
        return ll1

    if (ll1.data < ll2.data):
        ll1.next = merge_lists(ll1.next, ll2)
        return ll1
    else:
        ll2.next = merge_lists(ll2.next, ll1)
        return ll2

将输入输入列表。

l1 = []
try:
    l1 = list(map(int,input().strip().split()))
except EOFError:
    pass
l2 = []
try:
    l2 = list(map(int,input().strip().split()))
except EOFError:
    pass

根据输入列表值创建链接列表,即 ll1 ll2

ll1 = linkedlist()
ll1.head = Node(l1[0])
itr1 = ll1.head
for i in range(1,n1):
    temp = Node(l1[i])
    itr1.next = temp
    itr1 = itr1.next

ll2 = linkedlist()
ll2.head = Node(l2[0])
itr2 = ll2.head
for i in range(1,n2):
    temp = Node(l2[i])
    itr2.next = temp
    itr2 = itr2.next

通过传递两个链接列表的头部,使用合并功能合并两个排序的链接列表

itr = merge(ll1.head,ll2.head)

“合并”函数返回一个迭代器本身,其值打印为:

while itr != None:
    print(itr.data,end=" ")
    itr = itr.next

自定义输入和输出:-

输入

1

4

1 3 5 7

4

2 4 6 12

输出

1 2 3 4 5 6 7 12

答案 3 :(得分:0)

对我来说,将LinkedList转换为列表并返回更具Python性。 我还实现了打印功能来输出LinkedList,这有助于测试和调试。

library(dplyr)
library(tidyr)
library(ggplot2)

df <- read.table(text = "sample   start   type   source
  A      2,3,4    D2      BS
  B      5,6      D2      BS
  C      7,2,1    D3      AT
  D      8        D2      BS
  E      1,2,8,1  D3      BS
  F      4,3,3    D3      AT
  G      1,1      D2      BS
  H      2,9      D2      AT", header = TRUE) 

   df <- separate(df, col = start, into = c("var1", "var2", "var3")) %>% 
    pivot_longer(cols = matches("var\\d"), values_to = "start" , values_drop_na = TRUE)


df

# A tibble: 19 x 5
   sample type  source name  start
   <chr>  <chr> <chr>  <chr> <chr>
 1 A      D2    BS     var1  2    
 2 A      D2    BS     var2  3    
 3 A      D2    BS     var3  4    
 4 B      D2    BS     var1  5    
 5 B      D2    BS     var2  6    
 6 C      D3    AT     var1  7    
 7 C      D3    AT     var2  2    
 8 C      D3    AT     var3  1    
 9 D      D2    BS     var1  8    
10 E      D3    BS     var1  1    
11 E      D3    BS     var2  2    
12 E      D3    BS     var3  8    
13 F      D3    AT     var1  4    
14 F      D3    AT     var2  3    
15 F      D3    AT     var3  3    
16 G      D2    BS     var1  1    
17 G      D2    BS     var2  1    
18 H      D2    AT     var1  2    
19 H      D2    AT     var2  9  
 
ggplot(df, aes(type, start, col = type)) +
    geom_boxplot()

答案 4 :(得分:0)

首先让我说清楚,这是我提到的leet代码的问题,所以在这里我只是想回答这个问题,逻辑本身。

时间复杂度:O(n+m),其中 n 是 len(l1),m 是 len(l2),因为我们只遍历一次。

空间复杂度:O(1),我们不创建任何新对象,只是相互重新连接。

 class ListNode:
     def __init__(self, val=0, next=None):
        self.val = val
        self.next = next
 class Solution:
     def mergeTwoLists(self, l1, l2):
        head = res = ListNode()
    
        while l1 and l2:
            if l1.val <= l2.val:
                res.next = l1
                l1 = l1.next
            else:
                res.next = l2
                l2 = l2.next
            res = res.next
        if l1: res.next = l1
        if l2: res.next = l2
        return(head.next)

#创建一个新的链表,用于存储结果

#here 我对同一个列表使用了两个引用,因为我应该返回列表的根

#head 将在过程中使用,并返回 res。 ——