【算法设计题】合并两个非递减有序链表,第1题(C/C++)

目录

[第1题 合并两个非递减有序链表](#第1题 合并两个非递减有序链表)

得分点(必背)

题解

函数声明与初始化变量:

初始化合并链表的头节点:

合并两个链表:

处理剩余节点:

返回合并后的链表:

完整测试代码


🌈 嗨,我是命运之光

🌌 2024,每日百字,记录时光,感谢有你,携手前行~

🚀 携手启航,我们一同深入未知的领域,挖掘潜能,让每一步成长都充满意义。


第1题 合并两个非递减有序链表

已知 带头节点 单链表 LA LB ,其元素均为 非递减有序排列 ,编写算法 利用原表结点空间 ,将链表 LA LB 合并为 非递减有序序列 的单链表 LC

得分点(必背)

cpp 复制代码
// 合并两个非递减有序链表(得分点)
LinkList mergeLists(LinkList lista, LinkList listb){
    LinkList listc, p = lista, q = listb, r;
//listc指向lista 和 listb所指结点中较小者
//初始化合并链表的头节点
    if(lista->data<=listb->data){
        listc=lista;
        r=lista;
        p=lista->next;
    }
    else{
        listc=listb;
        r=listb;
        q=listb->next;
    }
//合并两个链表
    while(p!=NULL && q!=NULL){
        if(p->data<=q->data){
            r->next=p;
            r=p;
            p=p->next;
        }
        else{
            r->next=q;
            r=q;
            q=q->next;
        }
    }
    r->next=(p!=NULL)?p:q; //处理剩余节点
    return listc; //返回合并后的链表
}

题解

这段代码的功能是将两个非递减有序链表合并成一个非递减有序链表。下面我将逐步解释这段代码:

函数声明与初始化变量
cpp 复制代码
LinkList mergeLists(LinkList lista, LinkList listb){
    LinkList listc, p = lista, q = listb, r;
  • LinkList mergeLists(LinkList lista, LinkList listb):函数名为mergeLists,参数是两个非递减有序链表listalistb,返回值是合并后的链表。
  • LinkList listc, p = lista, q = listb, r;:定义了四个指针变量:
    • listc:用于指向合并后的链表的头节点。
    • p:初始化为指向链表lista的当前节点。
    • q:初始化为指向链表listb的当前节点。
    • r:用于构建合并后的链表。
初始化合并链表的头节点
cpp 复制代码
if(lista->data<=listb->data){
    listc=lista;
    r=lista;
    p=lista->next;
}
else{
    listc=listb;
    r=listb;
    q=listb->next;
}

if(lista->data<=listb->data):比较listalistb的头节点数据。

  • 如果lista的头节点数据小于等于listb的头节点数据:
    • listc = lista:将合并链表的头节点指向lista的头节点。
    • r = listar指向当前合并链表的最后一个节点(此时是lista的头节点)。
    • p = lista->next:将指针p移动到lista的下一个节点。
  • 否则:
    • listc = listb:将合并链表的头节点指向listb的头节点。
    • r = listbr指向当前合并链表的最后一个节点(此时是listb的头节点)。
    • q = listb->next:将指针q移动到listb的下一个节点。
合并两个链表
cpp 复制代码
while(p!=NULL && q!=NULL){
    if(p->data<=q->data){
        r->next=p;
        r=p;
        p=p->next;
    }
    else{
        r->next=q;
        r=q;
        q=q->next;
    }
}

while(p!=NULL && q!=NULL):循环遍历listalistb,直到其中一个链表遍历完(pq变为NULL)。

  • if(p->data<=q->data):比较pq指向的节点数据。
    • 如果p的数据小于等于q的数据:
      • r->next=p:将当前合并链表的最后一个节点的next指针指向p
      • r=p:将r指向p,即更新当前合并链表的最后一个节点。
      • p=p->next:将指针p移动到lista的下一个节点。
    • 否则:
      • r->next=q:将当前合并链表的最后一个节点的next指针指向q
      • r=q:将r指向q,即更新当前合并链表的最后一个节点。
      • q=q->next:将指针q移动到listb的下一个节点。
处理剩余节点
cpp 复制代码
r->next=(p!=NULL)?p:q;

r->next=(p!=NULL)?p:q;:当while循环结束时,可能还剩下一个链表中有未处理完的节点。

  • 如果p不为空,则将r->next指向p,即将剩余的lista节点连接到合并链表的末尾。
  • 如果p为空,则将r->next指向q,即将剩余的listb节点连接到合并链表的末尾。
返回合并后的链表
cpp 复制代码
return listc;
  • return listc;:返回合并后的链表listc

总结:这段代码通过比较两个链表的节点数据,将较小的数据节点依次连接到合并后的链表中,最终返回一个合并后的非递减有序链表。

完整测试代码

cpp 复制代码
#include<iostream>
using namespace std;

// 定义链表节点结构
struct Node {
int data;
Node* next;
};
// 定义 LinkList 类型为指向 Node 的指针
typedef Node* LinkList;
// 初始化链表
void InitList(LinkList& L){
    L=new Node;
    L->next=NULL;
}
// 合并两个非递减有序链表(得分点)
LinkList mergeLists(LinkList lista, LinkList listb){
    LinkList listc, p = lista, q = listb, r;
    //lilistc指向lista 和 listb所指结点中较小者
    if(lista->data<=listb->data){
        listc=lista;
        r=lista;
        p=lista->next;
    }
    else{
        listc=listb;
        r=listb;
        q=listb->next;
    }

    while(p!=NULL && q!=NULL){
        if(p->data<=q->data){
            r->next=p;
            r=p;
            p=p->next;
        }
        else{
            r->next=q;
            r=q;
            q=q->next;
        }
    }
    r->next=(p!=NULL)?p:q;
    return listc;
}
// 打印链表
void printList(LinkList head) {
    while (head != nullptr) {
        cout << head->data << " ";
        head = head->next;
    }
    cout << endl;
}

int main() {
    // 创建链表 a: 1 -> 3 -> 5
    Node* a1 = new Node{1, nullptr};
    Node* a2 = new Node{3, nullptr};
    Node* a3 = new Node{5, nullptr};
    a1->next = a2;
    a2->next = a3;

    // 创建链表 b: 2 -> 4 -> 6
    Node* b1 = new Node{2, nullptr};
    Node* b2 = new Node{4, nullptr};
    Node* b3 = new Node{6, nullptr};
    b1->next = b2;
    b2->next = b3;

    // 合并链表
    LinkList mergedList = mergeLists(a1, b1);

    // 打印结果
    printList(mergedList); // 应该输出: 1 2 3 4 5 6

    // 清理内存
    while (mergedList != nullptr) {
        Node* temp = mergedList;
        mergedList = mergedList->next;
        delete temp;
    }

    return 0;
}

嗨,我是命运之光。如果你觉得我的分享有价值,不妨通过以下方式表达你的支持:👍 点赞来表达你的喜爱,📁 关注以获取我的最新消息,💬 评论与我交流你的见解。我会继续努力,为你带来更多精彩和实用的内容。

点击这里👉 ,获取最新动态,⚡️ 让信息传递更加迅速。

相关推荐
永远都不秃头的程序员(互关)1 小时前
【决策树深度探索(四)】揭秘“混乱”:香农熵与信息纯度的量化之旅
算法·决策树·机器学习
永远都不秃头的程序员(互关)1 小时前
【决策树深度探索(三)】树的骨架:节点、分支与叶子,构建你的第一个分类器!
算法·决策树·机器学习
Σίσυφος19001 小时前
OpenCV - SVM算法
人工智能·opencv·算法
清酒难咽7 小时前
算法案例之递归
c++·经验分享·算法
让我上个超影吧8 小时前
【力扣26&80】删除有序数组中的重复项
算法·leetcode
张张努力变强9 小时前
C++ Date日期类的设计与实现全解析
java·开发语言·c++·算法
沉默-_-9 小时前
力扣hot100滑动窗口(C++)
数据结构·c++·学习·算法·滑动窗口
钱彬 (Qian Bin)9 小时前
项目实践19—全球证件智能识别系统(优化检索算法:从MobileNet转EfficientNet)
算法·全球证件识别
feifeigo1239 小时前
基于EM算法的混合Copula MATLAB实现
开发语言·算法·matlab
鑫—萍9 小时前
嵌入式开发学习——STM32单片机入门教程
c语言·驱动开发·stm32·单片机·嵌入式硬件·学习·硬件工程