牛客网刷题-合并两个排序的链表

本文介绍了学习嵌入式系统时C语言和数据结构的重要性,并通过合并两个排序链表的题目详细解析了解题过程和代码优化。提出了从基础到进阶的刷题策略,强调了动手实践和理解思路对于提升编程及面试能力的关键作用。同时,分享了如何通过调整代码结构来提高效率。

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

前言:
想要学好嵌入式,C语言与数据结构是必要熟练掌握的,而想熟练掌握一门语言,必须经过大量的练习,刷题,至少需要一两万行的代码量,才能具有一定的编程能力,至少拿到一个功能,怎么去用编程语言去实现它,从现在开始我要开启刷题之路,提高自己的编程水平,还有最重要的面试能力。
推荐一款刷题神器

一.合并两个排序的链表

题目原型:
在这里插入图片描述
输入输出示例:
在这里插入图片描述
1.题目分析:两个有序链表合并成一个新的有序链表,有几种特殊情况当两个链表为空则新链表为空,其中一个链表为空则新链表为另一个不为空的链表。

2.解题思路:
逐一比较两个链表中的结点的结点值,取小的尾插到新链表上。
在这里插入图片描述

代码实现:

struct ListNode* Merge(struct ListNode* pHead1, struct ListNode* pHead2 ) {
    // write code here
    struct ListNode* cur1=pHead1;
    struct ListNode* cur2=pHead2;
    struct ListNode* phead=NULL,*Ptail=NULL;
    //cur1为空返回cur2,cur2为空返回cur1,cur1,cur2都为空返回空
    if(cur1 ==NULL )
        return cur2;
    if(cur2 == NULL )
        return cur1;
    
    //找小的尾插到新链表
    while(cur1 !=NULL && cur2 !=NULL)
    {
       if(cur1->val < cur2->val )
       {
           if(phead == NULL)
           {
             Ptail=phead=cur1;
           } 
           else
           {
             Ptail->next=cur1;
             Ptail=cur1;  
           }  
           cur1=cur1->next; 
       }
       else
       {
          if(phead == NULL)
           {
             Ptail=phead=cur2;
           } 
           else
           {
             Ptail->next=cur2;
             Ptail=cur2;  
           }  
           cur2=cur2->next;    
       }
    }
    //如果cur1为空将cur2后面的结点全部尾插到新链表
    //如果cur2为空将cur1后面的结点全部尾插到新链表
    if(cur1 == NULL)
        Ptail->next=cur2;
    else
        Ptail->next=cur1;
    
    return phead; 
}

上面的代码虽然可以跑过,但是每次进入循环都要判断新链表是否为空(插入第一个结点)有点浪费CPU,其实我们只需要判断一次,让新链表首先插入一个结点,则后面插入结点直接尾插结点就好了。

  • 优化1:在新链表中先插入一个结点
    在这里插入图片描述
    优化代码1:
//优化1:提出循环外
struct ListNode* Merge(struct ListNode* pHead1, struct ListNode* pHead2 ) {
    // write code here
    struct ListNode* cur1=pHead1;
    struct ListNode* cur2=pHead2;
    struct ListNode* phead=NULL;
    struct ListNode* Ptail=NULL;
    if(cur1 ==NULL )
        return cur2;
    if(cur2 == NULL )
        return cur1;
    if( cur1->val < cur2->val )
    {
        Ptail=phead=cur1;
        cur1=cur1->next;
    }  
    else
    {
        Ptail=phead=cur2;
        cur2=cur2->next;
    }
    while(cur1 !=NULL && cur2 !=NULL)
    {
       if(cur1->val < cur2->val )
       {
           Ptail->next=cur1;
           cur1=cur1->next; 
       }
       else
       {
           Ptail->next=cur2;
           cur2=cur2->next;    
       }
          Ptail=Ptail->next;
    }
    if(cur1 == NULL)
        Ptail->next=cur2;
    else
        Ptail->next=cur1;
    
    return phead; 
}
  • 优化2:将新链表设计成一个带头结点的链表
    在这里插入图片描述
    优化代码2:

//优化2:添加头结点
struct ListNode* Merge(struct ListNode* pHead1, struct ListNode* pHead2 ) {
    // write code here
    struct ListNode* cur1=pHead1;
    struct ListNode* cur2=pHead2;
    struct ListNode* Ptail=NULL,*phead=NULL;
    phead=Ptail=(struct ListNode*)malloc(sizeof(struct ListNode));
    //cur1为空返回cur2,cur2为空返回cur1,cur1,cur2都为空返回空
    if(cur1 ==NULL )
        return cur2;
    if(cur2 == NULL )
        return cur1;
    //找小的尾插到新结点
    while(cur1 !=NULL && cur2 !=NULL)
    {
       if(cur1->val < cur2->val )
       {
           Ptail->next=cur1;
           cur1=cur1->next; 
       }
       else
       {
           Ptail->next=cur2;
           cur2=cur2->next;    
       }
         Ptail=Ptail->next;;
    }
    //如果cur1为空将cur2后面的结点全部尾插到新链表
    //如果cur2为空将cur1后面的结点全部尾插到新链表
    if(cur1 == NULL)
        Ptail->next=cur2;
    else
        Ptail->next=cur1;
    //记录第一个有效结点,释放头结点
    struct ListNode* first=phead->next;
    free(phead);
    return first; 
}

二.如何高效刷题

如何刷题:
1.如果你是基础不太好,可以先按照题解,跟着手打代码,重点理解题目思路,将题目所用到的知识点,解题技巧提炼出来(锻炼代码能力,解题思路)。在这里插入图片描述
2.当有一定的代码能力之后,但是看题还是没有思路,可以先看解题思路理解它,然后尝试用代码去实现它。(主要锻炼代码能力,进一步锻炼解题思维)

3.拿到一个题目自己先尝试解题,最好是能将解题思路用画图的方式体现出来,这样更能加深印象,然后用代码实现,实现之后再看看题解,或者别人的解题方法,进行对比,找到最优解题思路
在这里插入图片描述
最后:在解题过程中,碰到问题如下图(题目提交后通不过,报错(代码可能有bug),尽量独立思考,可以先尝试用它的测试用例,一步一步走读代码,看看问题出现在那个地方,如果实在是没有看出来,可以将该函数拷贝到VS中进行调试代码,一定能找出来。(锻炼自己的代码调试能力)

总结:
要想学好嵌入式C语言是根本,但是也离不开数据结构,尤其是链表、队列方面的知识,就接下来我要更新的freerots实时操作系统,就需要用到大量的链表和队列的知识,要想提高自己的编程水平,笔试能力和面试技巧,就得大量刷题手打代码

<think>嗯,用户是湖南的专升本考生,还有两个月就要考试了,想学好数据结构(C语言版)。首先得考虑他的背景和目标。专升本的学生可能在专科阶段学过一些编程基础,但可能不够扎实,特别是数据结构和算法部分,对于他们来说可能比较难。现在时间只有两个月,需要高效复习。 首先,用户的需求是学好数据结构,应对考试。但可能还存在一些隐含需求,比如时间紧迫,需要重点突破,掌握常考知识点,同时提升应试技巧。可能需要制定一个高效的学习计划,合理分配时间,抓住重点,多做,特别是真数据结构的内容很多,两个月时间不可能面面俱到,所以需要明确考试纲,确定重点章节。比如线性、栈和队列、树、图、排序和查找这些通常是考试重点。而像外部排序、高级树结构可能考得少,可以适当减少时间。 然后是学习方法。用户使用C语言版,所以需要确保C语言基础过关,比如指针、结构体、动态内存分配这些,如果这些不熟,会影响数据结构的实现。所以可能需要先快速复习C语言的关键部分。 接下来,分阶段学习。第一阶段打基础,约2周,复习C语言,然后逐个突破重点数据结构,比如线性、栈、队列,实现它们的操作,理解逻辑结构和物理结构。第二阶段,3周,深入树、图、排序查找,这里树和图可能比较复杂,尤其是遍历、最短路径、最小生成树等。同时要开始做,特别是算法,比如二叉树的遍历、图的DFS/BFS。第三阶段,2周,做真和模拟,查漏补缺,总结错,背诵基础概念,比如各种算法的时间复杂度,稳定性等。 需要注意的点是,要边学边写代码,理解算法的最好方法就是手动实现。比如链表的各种操作,自己写一遍才能发现细节问。另外,做时要先理解再记忆,特别是常见型,比如给一个序列,写出排序过程,或者构造二叉树。错本也很重要,避免重复错误。 还有时间管理,每天至少3小时,保持连贯。避免疲劳战,适当休息。心态调整也很重要,两个月足够提升,但要坚持。 可能用户没有提到的困难是,自学时遇到难无法解决,或者代码调试困难。建议寻找学习伙伴,或者在线资源、论坛提问。比如力扣、牛客网,或者看网课加深理解。 总结下来,计划要明确,抓住重点,多实践,多做,尤其是真,同时巩固C语言基础,分阶段推进,保持积极心态。</think>作为湖南专升本考生,在两个月内高效备考数据结构(C语言版),可以按照以下策略分阶段突破: ### 一、明确考试重点(1天) 1. 获取考纲:联系学校或查阅官网,明确考试范围(如线性、栈/队列、树、图、排序、查找必考) 2. 真分析:搜集近3年真,统计高频考点(如二叉树遍历、链表操作、快速排序等) ### 二、分阶段学习计划 #### ▶ 第一阶段:基础攻坚(2周) 1. **C语言速补**(3天) - 重点攻克:指针操作(二级指针处理链表)、结构体嵌套、动态内存管理(malloc/free) - 每日练习:手写链表创建/删除代码(含头结点版本) 2. **线性结构突破**(4天) - 线性:实现动态数组扩容策略(realloc使用) - 链表:完成带环链表检测(快慢指针法)、双向链表插入删除 - 栈/队列:用数组和链表各实现一次循环队列 #### ▶ 第二阶段:核心深化(3周) 1. **树结构精研**(7天) - 二叉树:非递归遍历(使用栈模拟)、线索二叉树构造 - BST:实现插入/删除节点后的平衡检测 - 哈夫曼树:手写编码过程(优先级队列实现) 2. **图论实战**(5天) - 存储:邻接矩阵与邻接的转换实现 - 遍历:BFS求最短路径(队列应用) - 算法:手写Prim算法逐步构造最小生成树 3. **排序与查找**(5天) - 排序:手写快速排序递归/非递归版本 - 查找:实现B树插入分裂过程(分步画图) #### ▶ 第三阶段:真淬炼(2周) 1. **模拟实战**(10天) - 每日完成1套真(严格计时) - 重点型专练:算法设计(如逆转链表、二叉树高度计算) 2. **错重做系统** - 典型错例:指针丢失(链表操作)、递归终止条件错误 ### 三、关键提分技巧 1. **代码可视化**: - 对复杂算法(如Dijkstra)使用格逐步演算 - 用纸笔模拟栈帧变化(递归算法) 2. **复杂度速判法**: - 嵌套循环 → O(n²) - 分治+合并 → O(nlogn) - 树操作 → O(h) 3. **应试锦囊**: - 算法先写伪代码再补充细节 - 代码注释标注关键步骤(可能获得步骤分) ### 四、每日时间示例 ``` 8:00-9:30 概念记忆(如B树性质) 10:00-12:00 代码实现(如平衡二叉树旋转) 14:00-16:00 真训练(严格计时) 19:00-21:00 错分析+针对性强化 ``` ### 五、推荐资源 1. 可视化工具:VisuAlgo(算法动态演示) 2. 平台:PTA《数据结构与算法目集》 3. 本地调试:VS Code配置C语言调试环境(断点调试链表) 最后两周建议进行三次全真模考,训练时间分配能力。注意考试中C语言常见扣分点:野指针、内存泄漏、数组越界等,代码务必写边界条件检测。坚持每日代码量保持手感,两个月冲刺完全可以实现质的突破!
评论 37
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

rivencode

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值