合并两个单链表(链表方式)

本文详细介绍了如何将两个已排序的单链表合并成一个新的排序单链表的算法实现。通过具体的C语言代码示例,展示了算法的具体步骤,包括初始化链表、创建链表、打印链表以及合并链表的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

假设头指针为La、Lb单链表分别为线性表LA、LB的存储结构,现在要合并La、Lb得到单链表Lc

void MergeList_L(LinkList La, LinkList Lb, LinkList Lc){
    //已知La、Lb的元素按值非递减排列
    //归并La、Lb得到单链表Lc,Lc的元素也是按值非递减排列的
    LinkList pa,pb,pc;
    pa = La->next;
    pb = Lb->next;
    Lc = pc = La;//用La的头结点作为Lc的头结点
    while(pa && pb){
        if(pa->data<=pb->data){
            pc->next = pa;
            pc = pa;
            pa = pa->next;
        }
        else{
            pc->next = pb;
            pc = pb;
            pb = pb->next;
        }
    }
    pc->next = pa?pa:pb;//插入剩余段 
    free(Lb); 
}

 链表合并实例:

 1 #include<stdio.h>
 2 #include<malloc.h>
 3 #include<stdlib.h>
 4 #include<string.h>
 5 #include<iostream>
 6 using namespace std;
 7 #define OVERFLOW -2
 8 typedef struct Node{
 9     int data;
10     struct Node *next;
11 }Node,*LinkList;
12 
13 int InitList(LinkList &L){
14     L = (LinkList)malloc(sizeof(Node));
15     if(!L)
16         exit(OVERFLOW);
17     L->next = NULL;
18     return 1;
19 }
20 
21 
22 
23 void CreatList(LinkList &L, int n){
24     LinkList p,r;
25     r = L;
26     int a;
27     for(int i = 0; i < n; i++){
28         p = (LinkList)malloc(sizeof(Node));
29         scanf("%d",&a);
30         p->data = a;
31         r->next = p;
32         r = p;
33     }
34     r->next = NULL;
35 }
36 
37 void PrintList(LinkList &L){//输出单链表 
38     LinkList q;
39     q = L->next;
40     while(q){ 
41         printf("%d ",q->data);
42         q = q->next;
43     }  
44 }
45 
46 void Combine(LinkList La, LinkList Lb, LinkList Lc){
47     LinkList pa,pb,pc;
48     pa = La->next;
49     pb = Lb->next;
50     Lc = pc = La;
51     while(pa && pb){
52         if(pa->data <= pb->data){
53             pc->next = pa;
54             pc = pa;
55             pa = pa->next;
56         }
57         else{
58             pc->next = pb;
59             pc = pb;
60             pb = pb->next;
61         }
62     }
63     pc->next = pa? pa:pb;
64     free(Lb);
65     PrintList(Lc);
66 }
67 
68 int main(){
69        int m,n;
70     LinkList LA,LB;
71     InitList(LA);
72     InitList(LB);
73     cout<<"请输入创建单链表LA的元素个数:";
74     cin>>m;
75     CreatList(LA,m);
76     cout<<"请输入创建单链表LB的元素个数:";
77     cin>>n;
78     CreatList(LB,n);
79     cout<<endl; 
80     cout<<"     链表LA中的元素"<<endl;
81     cout<<"-----------------------\n";
82     PrintList(LA);
83     cout<<endl; 
84     cout<<"\n\n     链表LB中的元素"<<endl;
85     cout<<"-----------------------\n";
86     PrintList(LB);
87     cout<<"\n\nLA、LB合并后的输出结果:"<<endl;
88     LinkList Lc;
89     InitList(Lc);
90     Combine(LA,LB,Lc); 
91     return 0; 
92 }

运行结果:

 

转载于:https://www.cnblogs.com/geziyu/p/9903351.html

<think>好的,用户想知道如何在Python中合并两个有序单链表。首先,我需要回忆一下链表的基本操作。合并两个有序链表通常有两种方法:递归和迭代。用户可能需要具体的示例代码,所以我要分别准备这两种方法的实现。 根据引用中的资料,递归方法的基本思路是比较两个链表当前节点的值,将较小的节点连接到结果链表中,并递归处理剩下的部分。比如引用[3]中的递归代码,处理了链表为空的情况,并递归设置next指针。不过递归可能会导致栈溢出,特别是当链表很长的时候,所以迭代方法可能更安全。 迭代方法则需要创建一个哨兵节点作为合并链表的起始点,然后用循环比较两个链表的当前节点,逐个连接较小的节点,直到其中一个链表遍历完。最后将剩余的链表直接接上。引用[2]和引用[3]都提到了迭代的实现,但用户提供的引用中的示例代码主要是递归,所以需要补充迭代的代码。 另外,用户需要代码示例,所以我要确保代码正确,并且符合Python的语法。比如在迭代方法中使用while循环,维护一个当前指针,逐个移动。同时,要注意处理链表可能为空的情况,避免空指针异常。 时间复杂度和空间复杂度分析也很重要。无论是递归还是迭代,时间复杂度都是$O(m + n)$,因为每个节点都会被访问一次。空间复杂度方面,递归由于调用栈的深度,可能需要$O(m + n)$,而迭代方法只需要常数空间,所以引用[1]中提到空间复杂度是O(1),可能是指迭代方法。 用户可能还关心代码的详细解释,比如函数的作用、参数的意义,以及如何创建和打印链表。因此,在代码说明部分,需要解释每个函数的功能,比如createNode、mergeTwoLists和printList,如引用[1]中的说明。 最后,生成相关问题的时候,应该围绕合并链表的不同方法、复杂度分析、应用场景等,帮助用户进一步学习。例如,递归和迭代的区别,如何处理特殊情况,以及合并链表算法中的应用。</think>### 分步说明:合并两个有序单链表 合并两个有序单链表的核心思路是**比较节点值并重新连接指针**,直到所有节点都按升序排列。以下是两种实现方式: --- #### **方法一:递归实现** 递归通过比较当前节点值,选择较小节点作为当前节点,并递归处理剩余链表: ```python class ListNode: def __init__(self, val=0, next=None): self.val = val self.next = next def merge_two_lists(l1: ListNode, l2: ListNode) -> ListNode: # 递归终止条件 if not l1: return l2 if not l2: return l1 # 选择较小值的节点作为当前节点 if l1.val <= l2.val: l1.next = merge_two_lists(l1.next, l2) return l1 else: l2.next = merge_two_lists(l1, l2.next) return l2 ``` **代码说明** - 终止条件:当某个链表为空时,直接返回另一个链表。 - 递归逻辑:比较两个链表当前节点的值,将较小节点的`next`指向递归结果[^3]。 --- #### **方法二:迭代实现** 使用哨兵节点简化边界条件,通过循环逐步合并链表: ```python def merge_two_lists(l1: ListNode, l2: ListNode) -> ListNode: dummy = ListNode(-1) # 哨兵节点简化操作 current = dummy while l1 and l2: if l1.val <= l2.val: current.next = l1 l1 = l1.next else: current.next = l2 l2 = l2.next current = current.next # 处理剩余节点 current.next = l1 if l1 else l2 return dummy.next ``` **代码说明** - 哨兵节点`dummy`用于统一处理头节点。 - `while`循环比较节点值,逐个连接较小节点。 - 剩余未遍历完的链表直接连接到末尾[^2]。 --- ### **复杂度分析** - **时间复杂度**:$O(m + n)$,其中$m$和$n$为两个链表的长度。每个节点仅被访问一次[^1]。 - **空间复杂度**: - 递归:$O(m + n)$(调用栈深度)。 - 迭代:$O(1)$(仅使用常数空间)。 --- ### **应用场景** 合并有序链表是基础算法问题,常用于: 1. 归并排序中的合并阶段。 2. 合并多个有序数据流(如日志文件)。 3. 数据库查询结果的有序合并。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值