2024重生之回溯数据结构与算法系列学习之王道第2.3章节之线性表精题汇总二(5)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】

本文涉及的产品
视觉智能开放平台,视频资源包5000点
视觉智能开放平台,图像资源包5000点
视觉智能开放平台,分割抠图1万点
简介: IKU达人之数据结构与算法系列学习×单双链表精题详解、数据结构、C++、排序算法、java 、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!

欢迎各位彦祖与热巴畅游本人专栏与博客

你的三连是我最大的动力

以下图片仅代表专栏特色 [点击箭头指向的专栏名即可闪现]

专栏跑道一

➡️网络空间安全——全栈前沿技术持续深入学习

image.gif

专栏跑道二

➡️ 24 Network Security -LJS

image.gif

image.gif

image.gif

专栏跑道三


➡️ MYSQL REDIS Advance operation

image.gif

专栏跑道四

➡️HCIP;H3C-SE;CCIP——LJS[华为、华三、思科高级网络]

image.gif

专栏跑道五

➡️RHCE-LJS[Linux高端骚操作实战篇]

image.png

专栏跑道六

➡️数据结构与算法[考研+实际工作应用+C程序设计]

image.gif

专栏跑道七

➡️RHCSA-LJS[Linux初级及进阶骚技能]

image.gif

image.gif

上节回顾





 目录

王道第2.3章节之线性表精题汇总二

(16)题目:两个整数序列A= ay, a2, a3, , am和B= b, b2, b3, , b,已经存入两个单链表中,设计一个算法,判断序列 B 是否是序列 A 的连续子序列。编辑

解题思路:

实现代码:

(17)题目:设计一个算法用于判断带头结点的循环双 链表Q是否对称。编辑

解题思路:

实现代码:

(18)题目:有两个循环 单链表Q,链表头指针分别为h1和h2,编写一个函数将链表h2链接到链表h1之后,要求链接后的链表仍保持循环链表形式。

解题思路:

实现代码:

(19)题目:设有一个带头结点的循环单链表Q,其结点值均为正整数,设计一个算法,反复找出单链表中结点值最小的结点并输出,然后将该结点从中删除,直到单链表空为止,再删除表头结点。

解题思路:

实现代码:

(20)题目:设头指针为L的带有表头结点的非循环双向链表,其每个结点中除有pred(前驱指针)、data(数据)和 next(后继指针)城外,还有一个访问频度域 freq。在链表被启用前,其值均初始化为零。每当在链表中进行一次Locate (L,x)运算时,令元素值为x的结点中freq域的值增1,并使此链表中结点保持按访问频度非增(递减)的顺序排列,同时最近访问的结点排在频度相同的结点前面,以使使频繁访问的结点总是靠近表头。试编写符合上述要求的 Locate (L,x)运算的算法,该运算为函数过程,返回找到结点的地址,类型为指针型。

解题思路:

实现代码:


(16)题目:两个整数序列A= ay, a2, a3, , am和B= b, b2, b3, , b,已经存入两个单链表中,设计一个算法,判断序列 B 是否是序列 A 的连续子序列。 image.gif 编辑

解题思路:

>KMP字符串比较算法
image.gif

实现代码:

#include <iostream>
using namespace std;
// 定义链表节点结构体
typedef struct LNode
{
    int data;          // 节点数据
    struct LNode *next; // 指向下一个节点的指针
} LNode, *LinkList;
// 头插法
void HeadInsert(LinkList &L)
{
    int val = 0;
    while (cin >> val) // 从标准输入读取整数值
    {
        LNode *s = new LNode; // 创建新节点
        s->data = val;        // 设置节点数据
        s->next = L->next;   // 将新节点的next指向当前链表的第一个节点
        L->next = s;         // 将头节点的next指向新节点
        if (cin.get() == '\n') // 如果输入回车,则结束输入
        {
            break;
        }
    }
}
// 尾插法
void TailInsert(LinkList &L)
{
    int val = 0;
    LNode *r = L; // r用于指向链表的尾部
    while (cin >> val) // 从标准输入读取整数值
    {
        LNode *s = new LNode; // 创建新节点
        s->data = val;        // 设置节点数据
        r->next = s;         // 尾节点的next指向新节点
        r = s;               // 更新尾节点为新节点
        r->next = NULL;      // 新节点的next指针为NULL
        if (cin.get() == '\n') // 如果输入回车,则结束输入
        {
            break;
        }
    }
}
// 遍历输出链表元素
void Print(LinkList L)
{
    LNode *p = L->next; // 从链表第一个节点开始
    while (p)
    {
        cout << p->data << '\t'; // 输出节点数据
        p = p->next;             // 移动到下一个节点
    }
    cout << endl; // 输出换行
}
// 判断链表B是否是链表A的子序列
void SubNode(LinkList &LA, LinkList &LB)
{
    LNode *p, *q, *pre; // LA、LB的工作结点,和每次开始的比较结点
    p = LA->next; // A链表的第一个节点
    q = LB->next; // B链表的第一个节点
    pre = p;      // pre用于记录当前匹配的位置
    while (p && q) // 当A和B都未遍历完时
    {
        // 如果二者相等,指针后移继续匹配
        if (p->data == q->data)
        {
            p = p->next; // A链表指针后移
            q = q->next; // B链表指针后移
        }
        // 不等,将pre开始指针向后偏移一位,q重新开始
        else
        {
            pre = pre->next; // pre后移
            p = pre;         // p指向pre
            q = LB->next;    // q重新指向B链表的头
        }
    }
    // 检查B链表是否完全遍历
    if (q)
    {
        cout << "B不是A的子序列" << endl; // 如果q没有遍历完,说明B不是A的子序列
        return;
    }
    cout << "B是A的子序列" << endl; // 如果q遍历完了,说明B是A的子序列
}
int main()
{
    LinkList LA = new LNode; // 创建链表A的头节点
    LinkList LB = new LNode; // 创建链表B的头节点
    TailInsert(LA); // 插入链表A的元素
    TailInsert(LB); // 插入链表B的元素
    SubNode(LA, LB); // 判断链表B是否是链表A的子序列
}
image.gif

(17)题目:设计一个算法用于判断带头结点的循环双 链表Q是否对称。 image.gif 编辑

解题思路:

>定义两个工作指针,一个从前向后扫描
>一个从后向前扫描
image.gif

实现代码:

#include <iostream>
using namespace std;
// 定义双向链表节点结构体
typedef struct LNode
{
    int data;                // 节点数据
    struct LNode *prior;    // 指向前一个节点的指针
    struct LNode *next;     // 指向下一个节点的指针
} LNode, *LinkList;
// 尾插法
void TailInsert(LinkList &L)
{
    int val = 0; // 用于存储输入的值
    LNode *r = L; // r指向链表的尾部
    while (cin >> val) // 从标准输入读取整数值
    {
        LNode *s = new LNode; // 创建新节点
        s->data = val;        // 设置节点数据
        r->next = s;         // 当前尾节点的next指向新节点
        s->prior = r;        // 新节点的prior指向当前尾节点
        r = s;               // 更新r为新节点
        if (cin.get() == '\n') // 如果输入回车,则结束输入
        {
            break;
        }
    }
    // 建立循环关系
    r->next = L; // 尾节点的next指向头节点
    L->prior = r; // 头节点的prior指向尾节点
}
// 遍历输出链表元素
void Print(LinkList L)
{
    LNode *p = L->next; // 从链表第一个节点开始
    while (p != L) // 当未到达头节点时
    {
        cout << p->data << '\t'; // 输出节点数据
        p = p->next;             // 移动到下一个节点
    }
    cout << endl; // 输出换行
}
// 判断循环链表是否对称
void JudgeSymmetry(LinkList &L)
{
    LNode *p, *q; // 定义工作结点,分别保存对应的前驱和后继
    p = L->next; // p指向链表的第一个节点
    q = L->prior; // q指向链表的最后一个节点
    // 二者不重合继续判断
    while (p != q)
    {
        // 偶数元素情况
        if (p->next == q && p->data == q->data)
        {
            cout << "该循环链表对称" << endl;
            return; // 找到对称,返回
        }
        // 奇数情况
        if (p->data != q->data)
        {
            cout << "该循环链表不对称" << endl;
            return; // 找到不对称,返回
        }
        else
        {
            p = p->next; // p指向下一个节点
            q = q->prior; // q指向前一个节点
        }
    }
    cout << "该循环链表对称" << endl; // 如果所有节点都匹配,说明对称
}
int main()
{
    LinkList L = new LNode; // 创建链表的头节点
    TailInsert(L); // 尾插法插入节点
    Print(L); // 打印链表
    JudgeSymmetry(L); // 判断链表是否对称
}
image.gif

(18)题目:有两个循环 单链表Q,链表头指针分别为h1和h2,编写一个函数将链表h2链接到链表h1之后,要求链接后的链表仍保持循环链表形式。

image.gif 编辑

解题思路:

>问题关键就是找到两个链表的尾指针
>然后修改指针指向
image.gif

实现代码:

#include <iostream>
using namespace std;
// 定义单向链表节点结构体
typedef struct LNode
{
    int data;               // 节点数据
    struct LNode *next;    // 指向下一个节点的指针
} LNode, *LinkList;
// 尾插法插入节点
void TailInsert(LinkList &L)
{
    int val = 0;           // 用于存储输入的值
    LNode *r = L;         // r指向链表的尾部
    while (cin >> val)    // 从标准输入读取整数值
    {
        LNode *s = new LNode; // 创建新节点
        s->data = val;        // 设置节点数据
        r->next = s;         // 当前尾节点的next指向新节点
        r = s;               // 更新r为新节点
        if (cin.get() == '\n') // 如果输入回车,则结束输入
        {
            break;
        }
    }
    r->next = L; // 尾节点的next指向头节点,形成循环链表
}
// 遍历输出链表元素
void Print(LinkList L)
{
    LNode *p = L->next; // 从链表第一个节点开始
    while (p != L)      // 当未到达头节点时
    {
        cout << p->data << '\t'; // 输出节点数据
        p = p->next;             // 移动到下一个节点
    }
    cout << endl; // 输出换行
}
// 连接两个循环链表 LA 和 LB
void ConnectList(LinkList &LA, LinkList &LB)
{
    LNode *pa, *pb; // 定义两个工作指针
    pa = LA->next; // pa 指向链表 LA 的第一个节点
    pb = LB->next; // pb 指向链表 LB 的第一个节点
    // 找到 LA 的尾指针
    while (pa->next != LA) // 遍历直到找到尾节点
    {
        pa = pa->next; // 移动到下一个节点
    }
    // 找到 LB 的尾指针
    while (pb->next != LB) // 遍历直到找到尾节点
    {
        pb = pb->next; // 移动到下一个节点
    }
    // 修改指针指向以连接两个链表
    pa->next = LB->next; // 将 LA 的尾节点连接到 LB 的第一个节点
    pb->next = LA;       // 将 LB 的尾节点连接到 LA
}
int main()
{
    LinkList LA = new LNode; // 创建链表 LA 的头节点
    LinkList LB = new LNode; // 创建链表 LB 的头节点
    TailInsert(LA); // 调用尾插法插入节点到 LA
    TailInsert(LB); // 调用尾插法插入节点到 LB
    ConnectList(LA, LB); // 连接两个链表 LA 和 LB
    Print(LA); // 打印连接后的链表 LA
}
image.gif

(19)题目:设有一个带头结点的循环单链表Q,其结点值均为正整数,设计一个算法,反复找出单链表中结点值最小的结点并输出,然后将该结点从中删除,直到单链表空为止,再删除表头结点。

image.gif 编辑

解题思路:

>定义几个工作指针
>每次遍历找到最小值将其删除
>直到表为空
image.gif

实现代码:

#include <iostream>
using namespace std;
// 定义单向链表节点结构体
typedef struct LNode
{
    int data;               // 节点数据
    struct LNode *next;    // 指向下一个节点的指针
} LNode, *LinkList;
// 尾插法插入节点
void TailInsert(LinkList &L)
{
    int val = 0;           // 用于存储输入的值
    LNode *r = L;         // r指向链表的尾部(初始为头节点)
    
    // 循环读取整数值
    while (cin >> val) 
    {
        LNode *s = new LNode; // 创建新节点
        s->data = val;        // 设置节点数据
        r->next = s;         // 当前尾节点的 next 指向新节点
        r = s;               // 更新 r 为新节点
        // 如果输入回车,则结束输入
        if (cin.get() == '\n') 
        {
            break;
        }
    }
    r->next = L; // 尾节点的 next 指向头节点,形成循环链表
}
// 遍历输出链表元素
void Print(LinkList L)
{
    LNode *p = L->next; // 从链表第一个节点开始
    while (p != L)      // 当未到达头节点时
    {
        cout << p->data << '\t'; // 输出节点数据
        p = p->next;             // 移动到下一个节点
    }
    cout << endl; // 输出换行
}
// 删除链表中最小值节点
void DelValue(LinkList &L)
{
    LNode *p, *pre, *minP, *minPre; // 定义工作节点和保存最小值及其前驱的指针
    // 只要链表不为空就搜索最小值
    while (L->next != L) 
    {
        // 重置指针
        p = minP = L->next; // p 和 minP 指向链表的第一个节点
        pre = minPre = L;   // pre 和 minPre 初始化为头节点
        // 遍历链表查找最小值
        while (p != L) 
        {
            if (p->data < minP->data) // 如果当前节点数据小于当前最小值
            {
                minP = p;            // 更新最小值节点
                minPre = pre;        // 更新最小值节点的前驱
            }
            pre = p;                   // 移动前驱指针
            p = p->next;              // 移动到下一个节点
        }
        cout << minP->data << '\t'; // 输出最小值
        minPre->next = minP->next; // 删除最小值节点
        delete minP;               // 释放内存
    }
    delete L; // 删除头节点
}
int main()
{
    LinkList L = new LNode; // 创建链表的头节点
    TailInsert(L); // 调用尾插法插入节点
    DelValue(L);   // 删除链表中的所有最小值节点
}
image.gif

(20)题目:设头指针为L的带有表头结点的非循环双向链表,其每个结点中除有pred(前驱指针)、data(数据)和 next(后继指针)城外,还有一个访问频度域 freq。在链表被启用前,其值均初始化为零。每当在链表中进行一次Locate (L,x)运算时,令元素值为x的结点中freq域的值增1,并使此链表中结点保持按访问频度非增(递减)的顺序排列,同时最近访问的结点排在频度相同的结点前面,以使使频繁访问的结点总是靠近表头。试编写符合上述要求的 Locate (L,x)运算的算法,该运算为函数过程,返回找到结点的地址,类型为指针型。

image.gif 编辑

解题思路:

>双链表的插入、删除
image.gif

实现代码:

#include <iostream>
using namespace std;
// 定义链表节点结构
typedef struct LNode
{
    int data;              // 节点数据
    int freq = 0;         // 节点频率,默认值为0
    struct LNode *pred;   // 前驱指针
    struct LNode *next;   // 后继指针
} LNode, *LinkList;
// 尾插法插入节点
void TailInsert(LinkList &L)
{
    int val = 0;          // 用于存储输入值
    LNode *r = L;        // r指向链表的最后节点
    while (cin >> val)   // 循环读取输入值
    {
        LNode *s = new LNode; // 创建新节点
        s->data = val;        // 设置节点数据
        r->next = s;         // 将新节点链接到链表
        r = s;               // 更新r指向新节点
        if (cin.get() == '\n') // 如果读取到换行符,结束输入
        {
            break;
        }
    }
    r->next = L;           // 形成循环链表
}
// 遍历输出链表元素
void Print(LinkList L)
{
    LNode *p = L->next;   // 从第一个有效节点开始
    while (p != L)        // 当未回到头节点时
    {
        cout << p->data << '\t'; // 输出节点数据
        p = p->next;          // 移动到下一个节点
    }
    cout << endl;          // 输出换行
}
// 定位节点并更新频率
LNode *Locate(LinkList &L, int x)
{
    LNode *p, *q;
    p = L->next;         // 从第一个有效节点开始
    while (p && p->data != x) // 查找数据为x的节点
    {
        p = p->next;
    }
    if (!p)              // 如果没有找到,返回NULL
    {
        return NULL;
    }
    else
    {
        p->freq++;       // 找到节点,频率加1
        // 如果该节点在链表头或前驱频率更大,直接返回
        if (p->pred == L || p->pred->freq > p->freq)
        {
            return p;
        }
        // 断开p节点与其前驱的链接
        if (p->next != NULL)
        {
            p->next->pred = p->pred;
        }
        p->pred->next = p->next;
        // 在前驱节点中寻找合适的位置插入p节点
        q = p->pred;
        while (q != L && q->freq <= p->freq)
        {
            q = q->pred;
        }
        // 更新p的前驱和后继指针
        p->next = q->next;
        if (q->next != NULL)
        {
            q->next->pred = p;
        }
        p->pred = q;
        q->next = p;
    }
    return p;            // 返回更新后的节点
}
int main()
{
    LinkList L = new LNode; // 创建链表头节点
    TailInsert(L);         // 尾插法插入节点
    LNode *p = Locate(L, 3); // 定位值为3的节点
}
image.gif

 

相关文章
|
3天前
|
弹性计算 双11 开发者
阿里云ECS“99套餐”再升级!双11一站式满足全年算力需求
11月1日,阿里云弹性计算ECS双11活动全面开启,在延续火爆的云服务器“99套餐”外,CPU、GPU及容器等算力产品均迎来了全年最低价。同时,阿里云全新推出简捷版控制台ECS Lite及专属宝塔面板,大幅降低企业和开发者使用ECS云服务器门槛。
|
21天前
|
存储 弹性计算 人工智能
阿里云弹性计算_通用计算专场精华概览 | 2024云栖大会回顾
阿里云弹性计算产品线、存储产品线产品负责人Alex Chen(陈起鲲)及团队内多位专家,和中国电子技术标准化研究院云计算标准负责人陈行、北京望石智慧科技有限公司首席架构师王晓满两位嘉宾,一同带来了题为《通用计算新品发布与行业实践》的专场Session。本次专场内容包括阿里云弹性计算全新发布的产品家族、阿里云第 9 代 ECS 企业级实例、CIPU 2.0技术解读、E-HPC+超算融合、倚天云原生算力解析等内容,并发布了国内首个云超算国家标准。
阿里云弹性计算_通用计算专场精华概览 | 2024云栖大会回顾
|
3天前
|
人工智能 弹性计算 文字识别
基于阿里云文档智能和RAG快速构建企业"第二大脑"
在数字化转型的背景下,企业面临海量文档管理的挑战。传统的文档管理方式效率低下,难以满足业务需求。阿里云推出的文档智能(Document Mind)与检索增强生成(RAG)技术,通过自动化解析和智能检索,极大地提升了文档管理的效率和信息利用的价值。本文介绍了如何利用阿里云的解决方案,快速构建企业专属的“第二大脑”,助力企业在竞争中占据优势。
|
1天前
|
人工智能 自然语言处理 安全
创新不设限,灵码赋新能:通义灵码新功能深度评测
自从2023年通义灵码发布以来,这款基于阿里云通义大模型的AI编码助手迅速成为开发者心中的“明星产品”。它不仅为个人开发者提供强大支持,还帮助企业团队提升研发效率,推动软件开发行业的创新发展。本文将深入探讨通义灵码最新版本的三大新功能:@workspace、@terminal 和 #team docs,分享这些功能如何在实际工作中提高效率的具体案例。
|
7天前
|
负载均衡 算法 网络安全
阿里云WoSign SSL证书申请指南_沃通SSL技术文档
阿里云平台WoSign品牌SSL证书是由阿里云合作伙伴沃通CA提供,上线阿里云平台以来,成为阿里云平台热销的国产品牌证书产品,用户在阿里云平台https://www.aliyun.com/product/cas 可直接下单购买WoSign SSL证书,快捷部署到阿里云产品中。
1850 6
阿里云WoSign SSL证书申请指南_沃通SSL技术文档
|
10天前
|
Web App开发 算法 安全
什么是阿里云WoSign SSL证书?_沃通SSL技术文档
WoSign品牌SSL证书由阿里云平台SSL证书合作伙伴沃通CA提供,上线阿里云平台以来,成为阿里云平台热销的国产品牌证书产品。
1789 2
|
19天前
|
编解码 Java 程序员
写代码还有专业的编程显示器?
写代码已经十个年头了, 一直都是习惯直接用一台Mac电脑写代码 偶尔接一个显示器, 但是可能因为公司配的显示器不怎么样, 还要接转接头 搞得桌面杂乱无章,分辨率也低,感觉屏幕还是Mac自带的看着舒服
|
26天前
|
存储 人工智能 缓存
AI助理直击要害,从繁复中提炼精华——使用CDN加速访问OSS存储的图片
本案例介绍如何利用AI助理快速实现OSS存储的图片接入CDN,以加速图片访问。通过AI助理提炼关键操作步骤,避免在复杂文档中寻找解决方案。主要步骤包括开通CDN、添加加速域名、配置CNAME等。实测显示,接入CDN后图片加载时间显著缩短,验证了加速效果。此方法大幅提高了操作效率,降低了学习成本。
5386 15
|
13天前
|
人工智能 关系型数据库 Serverless
1024,致开发者们——希望和你一起用技术人独有的方式,庆祝你的主场
阿里云开发者社区推出“1024·云上见”程序员节专题活动,包括云上实操、开发者测评和征文三个分会场,提供14个实操活动、3个解决方案、3 个产品方案的测评及征文比赛,旨在帮助开发者提升技能、分享经验,共筑技术梦想。
1139 152
|
21天前
|
存储 缓存 关系型数据库
MySQL事务日志-Redo Log工作原理分析
事务的隔离性和原子性分别通过锁和事务日志实现,而持久性则依赖于事务日志中的`Redo Log`。在MySQL中,`Redo Log`确保已提交事务的数据能持久保存,即使系统崩溃也能通过重做日志恢复数据。其工作原理是记录数据在内存中的更改,待事务提交时写入磁盘。此外,`Redo Log`采用简单的物理日志格式和高效的顺序IO,确保快速提交。通过不同的落盘策略,可在性能和安全性之间做出权衡。
1585 14

热门文章

最新文章

  • 1
    2024重生之回溯数据结构与算法系列学习之串(12)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丟脸好嘛?】
    12
  • 2
    2024重生之回溯数据结构与算法系列学习(11)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丟脸好嘛?】
    6
  • 3
    2024重生之回溯数据结构与算法系列学习之栈和队列精题汇总(10)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
    9
  • 4
    2024重生之回溯数据结构与算法系列学习之单双链表精题详解(9)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
    10
  • 5
    2024重生之回溯数据结构与算法系列学习(8)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
    10
  • 6
    2024重生之回溯数据结构与算法系列学习(7)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
    7
  • 7
    2024重生之回溯数据结构与算法系列学习之王道第2.3章节之线性表精题汇总二(5)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
    7
  • 8
    23
    6
  • 9
    2024重生之回溯数据结构与算法系列学习之单双链表精题(4)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
    9
  • 10
    2024重生之回溯数据结构与算法系列学习之单双链表【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
    6