【数据结构算法经典题目刨析(c语言)】合并两个有序链表

💓 博客主页:C-SDN花园GGbond

⏩ 文章专栏:数据结构经典题目刨析(c语言)

一.题目描述:

二.解题思路:

合并两个有序链表的思路

创建一个新的链表,将两个链表的节点元素按大小顺序逐个尾插到新的链表中,最后返回新链表的首节点地址

三.解题步骤:

1.先对两个链表进行判空,如果任意一个链表为空,直接返回另一个链表首节点地址
2.创建两个指针用来指向新链表的首节点和尾节点,初始都指向NULL
3.再创建两个指针p1 p2用来遍历两个有序链表,初始分别指向两个链表的首节点
4.然后进入while循环,当两个链表都未遍历完成时执行循环,先比较p1 和p2指向的节点的  元素大小,将较小的节点插入新链表的尾部
5.插入的过程——先判断新链表是否为空
   如果为空,新链表的首尾指针都指向该节点
   如果不为空,执行尾插。将新链表尾节点的next指针执行该节点,再将尾指针向后移动
   完成一个节点插入后,将该节点所属的链表的遍历指针向后移动
6.出循环后,说明两个链表其中有一个先遍历完成了
   此时进行判断,哪个指针指向空,就将另一个链表剩余节点挂在新链表尾部
7.最后,返回新链表的首节点指针

优化

存在问题——每次插入都要判断链表是否为空
解决办法——创建不存储数据的头结点,让链表不为空

不要忘记使用完成后对动态申请空间释放
最后返回新链表第一个有效节点的地址

四.优化后代码实现(c)

struct ListNode 
{   //单链表结构
    int val;
    struct ListNode* next;
    
};
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
{
    if (list1 == NULL)//先判断两个链表是否为空
        return list2;
    if (list2 == NULL)
        return list1;
 
    struct ListNode* newhead = (struct ListNode*)malloc(sizeof(struct ListNode));//新链表头节点指针
    struct ListNode* newtail = newhead;//新链表尾指针
 
    struct ListNode* p1 = list1;//遍历两个链表的指针
    struct ListNode* p2 = list2;
 
    while (p1 && p2)//两个链表都不为空执行循环
    {   //哪个链表节点数据小,就将其尾插到新链表
        if (p1->val > p2->val)
        {
            newtail->next = p2;
            p2 = p2->next;
        }
        else
        {
            newtail->next = p1;
            p1 = p1->next;
        }
        newtail = newtail->next;//新链表尾指针向后移动
    }
    //一定有一个链表先走到空,出循环后将另一个链表剩余节点尾插到新链表
    if (p1 == NULL)
    {
        newtail->next = p2;
    }
    if (p2 == NULL)
    {
        newtail->next = p1;
    }
    struct ListNode* ret = newhead->next;
    free(newhead);
    newhead = NULL;
    return ret;
}

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
假设我们有两个有序链表,分别是 head1 和 head2,链表中的每个节点都有一个 val 值和一个 next 指针,表示该节点的值和下一个节点的地址。我们需要将这两个有序链表合并成一个新的有序链表。 具体实现如下: ```c #include <stdio.h> #include <stdlib.h> struct ListNode { int val; struct ListNode *next; }; struct ListNode* mergeTwoLists(struct ListNode* head1, struct ListNode* head2){ // 创建一个新的链表 head,用于存储合并后的结果 struct ListNode *head = (struct ListNode *)malloc(sizeof(struct ListNode)); head->next = NULL; // 创建一个指针 p,用于指向新链表的尾部 struct ListNode *p = head; // 循环比较两个链表的节点,将小的节点加入到新链表中 while (head1 != NULL && head2 != NULL) { if (head1->val < head2->val) { p->next = head1; head1 = head1->next; } else { p->next = head2; head2 = head2->next; } p = p->next; } // 将剩余的节点加入到新链表中 if (head1 != NULL) { p->next = head1; } if (head2 != NULL) { p->next = head2; } // 返回新链表的头节点 return head->next; } int main() { // 创建两个有序链表 struct ListNode *head1 = (struct ListNode *)malloc(sizeof(struct ListNode)); struct ListNode *node1_1 = (struct ListNode *)malloc(sizeof(struct ListNode)); struct ListNode *node1_2 = (struct ListNode *)malloc(sizeof(struct ListNode)); head1->val = 1; node1_1->val = 3; node1_2->val = 5; head1->next = node1_1; node1_1->next = node1_2; node1_2->next = NULL; struct ListNode *head2 = (struct ListNode *)malloc(sizeof(struct ListNode)); struct ListNode *node2_1 = (struct ListNode *)malloc(sizeof(struct ListNode)); struct ListNode *node2_2 = (struct ListNode *)malloc(sizeof(struct ListNode)); head2->val = 2; node2_1->val = 4; node2_2->val = 6; head2->next = node2_1; node2_1->next = node2_2; node2_2->next = NULL; // 合并两个有序链表 struct ListNode *head = mergeTwoLists(head1, head2); // 输出合并后的结果 while (head != NULL) { printf("%d ", head->val); head = head->next; } printf("\n"); return 0; } ``` 以上代码中,我们创建了两个有序链表,分别是 head1 和 head2。然后我们定义了一个新的链表 head,用于存储合并后的结果。接着我们定义了一个指针 p,用于指向新链表的尾部。 我们循环比较两个链表的节点,将小的节点加入到新链表中。如果其中一个链表已经遍历完了,我们将剩余的节点加入到新链表中。 最后,我们返回新链表的头节点,并输出合并后的结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值