【算法与数据结构】707.、LeetCode设计链表

news2024/12/23 13:47:43

文章目录

  • 一、题目
  • 二、设计链表
  • 三、完整代码

所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。

一、题目

在这里插入图片描述

在这里插入图片描述

二、设计链表

  思路分析:这里我将的成员函数放在类外实现了,这样链表类看起来更加简洁,方便大家学习链表的结构,主要包含:节点类结构体,构造函数(构造函数也可以放在类外实现),成员函数和成员变量类的成员函数实现主要有两种,一种是类内实现,一种是类外实现,类外实现需要在类内写声明,然后在类外写实现。构造函数初始化一个虚假头结点和链表大小。关于虚假头结点,可以参考【算法与数据结构】203、LeetCode移除链表元素。
  链表类如下

// 链表类
class MyLinkedList {
public:   
    // 定义链表节点类结构体
    struct LinkNode {
        int val;
        LinkNode* next;
        LinkNode() : val(0), next(NULL) {};
        LinkNode(int input_val) : val(input_val), next(NULL) {};
        LinkNode(int input_val, LinkNode* input_next) : val(input_val), next(input_next) {};
    };
    // 构造函数
    MyLinkedList() {
        _FakeNode = new LinkNode(0);    // 虚假头结点
        _size = 0;
    }
// 成员函数
    int get(int index);
    void addAtHead(int val);
    void addAtTail(int val);
    void addAtIndex(int index, int val);
    void deleteAtIndex(int index);
    void ChainGenerator(int arr[], int len);
    void LinkListPrint(string str);
// 成员变量
private:
    int _size;
    LinkNode* _FakeNode;
};

  讲完整体构造,然后将各个部分。
  首先是get函数:进入链表首先判断index是否合法,然后链表从虚假头结点出发,利用index,当找到目标索引时,cur就指向这个值,index自减归于0退出循环

int MyLinkedList::get(int index) { 
    if (index > (_size - 1) || index < 0) return -1;
    LinkNode* cur = _FakeNode->next; // 头结点
    while (index--) {
        cur = cur->next;
    }
    return cur->val;
}

  addAtHead函数:这个函数比较简单,我们新建一个节点,指向虚节点的下一个节点(也就是插入之前的头结点),然后让虚节点指向新建节点,最后链表大小+1。

void MyLinkedList::addAtHead(int val) {
    LinkNode* pNewNode = new LinkNode(val, _FakeNode->next);
    _FakeNode->next = pNewNode;
    _size++;
}

  addAtTail函数:addTail函数需要遍历这个链表,找到尾节点,复杂度是 O ( n ) O(n) O(n),让尾节点指向新建节点即可。

void MyLinkedList::addAtTail(int val) {
    LinkNode* pNewNode = new LinkNode(val);
    LinkNode* cur = _FakeNode;
    while (cur->next != NULL) {
        cur = cur->next;
    }
    cur->next = pNewNode;
    _size++;
}

  addAtIndex函数:前两个函数都可以用这个函数实现,在这个函数中,首先根据题目条件判断index是否合法,令cur指针等于虚节点,同样使用index找到插入位置的上一个节点,然后就是链表的插入操作。

void MyLinkedList::addAtIndex(int index, int val) {   
    if (index > _size) return;
    if (index < 0) index = 0;
    LinkNode* cur = _FakeNode; // 虚结点 
    // 需要断开上一一个阶段的链接,从插入位置的上一个索引开始处理
    while (index--) {
        cur = cur->next;
    }
    LinkNode* pNewNode = new LinkNode(val, cur->next);
    cur->next = pNewNode;
    _size++;
}

  deleteAtIndex函数:这个函数可以参考【算法与数据结构】203、LeetCode移除链表元素。

void MyLinkedList::deleteAtIndex(int index) {     
    if (index > (_size - 1) || index < 0) return;
    LinkNode* cur = _FakeNode; // 头结点
    // 需要断开上一一个阶段的链接
    while (index--) {
        cur = cur->next;
    }
    LinkNode* tmp = cur->next;
    cur->next = cur->next->next;
    delete tmp;
    tmp = NULL;
    _size--;
}

  ChainGenerator函数和LinkListPrint函数:除了题目要求的函数以外,我还写了数组生成链表函数,以及链表打印函数。这两个函数在main函数中调用,方便调试。

void MyLinkedList::ChainGenerator(int arr[], int len) {
    LinkNode* head = new LinkNode(arr[0], NULL);
    LinkNode* p = head;
    for (int i = 1; i < len; i++) {
        LinkNode* pNewNode = new LinkNode(arr[i], NULL);
        p->next = pNewNode; // 上一个节点指向这个新建立的节点
        p = pNewNode; // p节点指向这个新的节点
    }
    _FakeNode->next = head;
    _size = len;
}
void MyLinkedList::LinkListPrint(string str) {
    cout << str << endl;
    LinkNode* cur = _FakeNode;
    while (cur->next != NULL) {
        cout << cur->next->val << ' ';
        cur = cur->next;
    }
    cout << endl;
}

三、完整代码

# include <iostream>
using namespace std;

// 链表类
class MyLinkedList {
public:   
    // 定义链表节点类结构体
    struct LinkNode {
        int val;
        LinkNode* next;
        LinkNode() : val(0), next(NULL) {};
        LinkNode(int input_val) : val(input_val), next(NULL) {};
        LinkNode(int input_val, LinkNode* input_next) : val(input_val), next(input_next) {};
    };
    // 构造函数
    MyLinkedList() {
        _FakeNode = new LinkNode(0);    // 虚假头结点
        _size = 0;
    }
// 成员函数
    int get(int index);
    void addAtHead(int val);
    void addAtTail(int val);
    void addAtIndex(int index, int val);
    void deleteAtIndex(int index);
    void ChainGenerator(int arr[], int len);
    void LinkListPrint(string str);
// 成员变量
private:
    int _size;
    LinkNode* _FakeNode;
};

// 类外实现链表的成员函数
int MyLinkedList::get(int index) { 
    if (index > (_size - 1) || index < 0) return -1;
    LinkNode* cur = _FakeNode->next; // 头结点
    while (index--) {
        cur = cur->next;
    }
    return cur->val;
}

void MyLinkedList::addAtHead(int val) {
    LinkNode* pNewNode = new LinkNode(val, _FakeNode->next);
    _FakeNode->next = pNewNode;
    _size++;
}

void MyLinkedList::addAtTail(int val) {
    LinkNode* pNewNode = new LinkNode(val);
    LinkNode* cur = _FakeNode;
    while (cur->next != NULL) {
        cur = cur->next;
    }
    cur->next = pNewNode;
    _size++;
}

void MyLinkedList::addAtIndex(int index, int val) {   
    if (index > _size) return;
    if (index < 0) index = 0;
    LinkNode* cur = _FakeNode; // 虚结点 
    // 需要断开上一一个阶段的链接,从插入位置的上一个索引开始处理
    while (index--) {
        cur = cur->next;
    }
    LinkNode* pNewNode = new LinkNode(val, cur->next);
    cur->next = pNewNode;
    _size++;
}

void MyLinkedList::deleteAtIndex(int index) {     
    if (index > (_size - 1) || index < 0) return;
    LinkNode* cur = _FakeNode; // 头结点
    // 需要断开上一一个阶段的链接
    while (index--) {
        cur = cur->next;
    }
    LinkNode* tmp = cur->next;
    cur->next = cur->next->next;
    delete tmp;
    tmp = NULL;
    _size--;
}

void MyLinkedList::ChainGenerator(int arr[], int len) {
    LinkNode* head = new LinkNode(arr[0], NULL);
    LinkNode* p = head;
    for (int i = 1; i < len; i++) {
        LinkNode* pNewNode = new LinkNode(arr[i], NULL);
        p->next = pNewNode; // 上一个节点指向这个新建立的节点
        p = pNewNode; // p节点指向这个新的节点
    }
    _FakeNode->next = head;
    _size = len;
}

void MyLinkedList::LinkListPrint(string str) {
    cout << str << endl;
    LinkNode* cur = _FakeNode;
    while (cur->next != NULL) {
        cout << cur->next->val << ' ';
        cur = cur->next;
    }
    cout << endl;
}

int main()
{
    int arr[] = { 6, 7, 2, 0, 4 };
    int len = sizeof(arr) / sizeof(int);
    MyLinkedList m1;
    m1.addAtIndex(1, 0);
     m1.LinkListPrint("打印链表:");
    int val1 = m1.get(0);
     cout << "目标索引的值:" << val1 << endl;

    system("pause");
    return 0;
}

end

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/623964.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mysql之uniquekey学习。

uniquekey就真的是唯一键了吗&#xff1f; 答案是不是的。可以允许多个重复null值的存在&#xff0c;版本5.73 CREATE TABLE student_uniq ( id int(11) DEFAULT NULL, name varchar(200) DEFAULT NULL, socre int(11) DEFAULT NULL, UNIQUE KEY s_uniq (socre,name) )…

【操作系统】Linux进阶必须掌握的进程、线程及调度算法~进程学习

Linux内核源代码中&#xff0c;进程的状态是用数字来表示的&#xff0c;为了弄明白正在运行的进程是什么意思&#xff0c;我们需要知道进程的不同状态。一个进程可以有几个状态&#xff08;在Linux内核里面&#xff0c;进程有时候也叫任务&#xff09; /* The task state arra…

【TA100】图形 2.6伽马(Gamma)校正

很好的视频 https://www.bilibili.com/video/BV15t411Y7cf/?spm_id_from333.788.b_636f6d6d656e74.96&vd_source6f3a5e0ac931d869aee3d7c9bb6847e0 一、Gamma校正 1.前言&#xff1a;颜色空间 ● 一些颜色空间的举例&#xff0c;&#xff08;具体参考2.1节内容&#xff0…

最大似然估计(MLE)VS 最大后验概率估计(MAP)

1、概率和统计是一个东西吗&#xff1f; 概率&#xff08;probabilty&#xff09;和统计&#xff08;statistics&#xff09;看似两个相近的概念&#xff0c;其实研究的问题刚好相反。 一句话总结&#xff1a;概率是已知模型和参数&#xff0c;推数据。统计是已知数据&#x…

普通学校计算机毕业生,从事网络安全行业可以吗?

如果你是普通大学、大专的计算机专业应届生&#xff0c;还在迷茫找工作&#xff0c;这篇内容希望你能认真看完&#xff0c;很可能会决定你的人生方向。 现在的高薪行业&#xff0c;除了明星就只能是程序员了。不信你问问身边的人想学哪个专业&#xff0c;他们肯定不假思索的说…

C++基础(三) —— 内存分配

文章目录 概念01 物理地址内存的分配与释放02 虚拟用户进程空间内存的分配与释放 03 allocator模板类04 new delete05 malloc free06 strcpy 与 memcpy 与 memsetstrcpymemcpymemset 概念 01 物理地址内存的分配与释放 主要采用链表结构 使用了一个名叫page的结构体管理物理…

基于nodejs实现text/event-stream简单应用案例,SSE

基于nodejs实现text/event-stream简单应用案例&#xff0c;SSE text/event-stream代码实现服务器端前端 效果 text/event-stream 是一种用于服务器向客户端推送事件的媒体类型&#xff08;Media Type&#xff09;。它是基于 HTTP 协议的一种流式传输技术&#xff0c;也被称为 …

揭秘新一代云数仓技术架构与最佳实践

从传统数仓到湖仓一体&#xff0c;历经三十多年发展&#xff0c;技术的浪潮快速迭代&#xff0c;以云原生数仓为中心的现代数据栈时代已然到来。 背后的核心的原因在于&#xff0c;企业正在加速走向数字化、智能化&#xff0c;对数据的应用也提出了全新要求&#xff0c;特别是对…

每日一练 | 华为认证真题练习Day55

1、RSTP协议配置BPDU中的Flag字段使用了哪些STP协议未使用的标志位&#xff1f;&#xff08;多选&#xff09; A. Agreement B. TCA C. TC D. Proposal 2、RSTP中Backup端口可以替换发生故障的根端口。 A. 对 B. 错 3、如下图所示的网络&#xff0c;在RouterA设备里面存在…

更适合中国打工人体质的报表工具,零代码自动生成老板满意模板!

“中国职场上大家公认最头疼的是什么&#xff1f;” “加班&#xff1f;裁员&#xff1f;薪资&#xff1f;” “一切的根源来源于哪&#xff1f;” “是因为做大大小小报表加班到深夜、是同事都在卷报表制作有人只能被动裁员&#xff0c;也是千篇一律的报表汇报决定了这职业…

FreeRTOS学习笔记(五)——应用开发(三)

文章目录 0x01 软件定时器应用场景定时器精度运作机制软件定时器控制模块函数接口xTimerCreate()prvInitialiseNewTimer()xTimerStart()xTimerGenericCommand()xTimerStartFromISR()xTimerStop()xTimerStopFromISR()xTimerDelete()软件定时器任务创建以及执行原理软件定时器实验…

如何优化档案库房管理?一招学会轻松提升效率

在现代企业运营中&#xff0c;档案库房扮演着重要的角色&#xff0c;承载着大量宝贵的纸质档案资料。这些档案包含着企业的历史、客户信息、法律文件等重要数据&#xff0c;对于企业的正常运转和决策制定至关重要。然而&#xff0c;传统的档案库房管理方式存在一系列的挑战和难…

深度刨析指针Advanced 1

作者主页&#xff1a;paper jie的博客_CSDN博客-C语言,算法详解领域博主 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 本文录入于《系统解析C语言》专栏&#xff0c;本专栏是针对于大学生&#xff0c;编程小白…

浅谈智能微电网供电系统的谐波治理

摘要&#xff1a;智能微电网供电系统的特性容易引发谐波&#xff0c;而谐波导致电力损耗加大&#xff0c;降低供电质量。本文从谐波的产 生原因和危害做出详细阐述&#xff0c;并结合智能微电网提出了治 理谐波的方法和措施。 关键词&#xff1a;智能微电网&#xff1b;谐波危害…

手术麻醉信息管理系统源码:全面监护,支持多设备采集

手术、麻醉是医院非常重要的一个组成部分&#xff0c;外科医生为病人进行手术的好与坏直接会危及到病人的生命&#xff0c;所以病人在手术麻醉过程中每一个环节都是非常重要的。随着现在高科技的发展&#xff0c;大量的医疗监视辅助仪器设备在手术过程中也得到广泛的应用&#…

Jenkins使用Docker(Podman)安装部署web应用

https://blog.csdn.net/onePageKownAll/article/details/128182290 https://blog.csdn.net/weixin_45647685/article/details/127825728 https://zhuanlan.zhihu.com/p/562495608 最终效果&#xff1a;在jenkins对某个项目进行构建&#xff0c;jenkins先通过git拉取最项目的…

MySQL基本知识复习补充

MySQL基本知识复习补充 SQL分类 DDL&#xff1a;数据定义语言。create、alter、drop、rename、truncate(清空表) DML&#xff1a;数据操作语言。insert、delete、update、select DCL&#xff1a;数据控制语言。commit、rollback、savepoint、grant、revoke 因为查询语句使…

最后机会!桥接 LAND 可以获得返还奖励!

经过 1 年的服务&#xff0c;The Sandbox 向我们的社区成员分发了超过 40 万 SAND&#xff0c;LAND 桥接返还奖励计划即将结束。 该计划是为了减轻土地持有者从以太坊桥接到 Polygon 的成本。每块土地的桥接都可获得 10 SAND 的奖励。 最后机会&#xff01;再次呼吁各位桥接 LA…

从小白到大神之路之学习运维第36天---第三阶段---mysql数据库之企业级mysql部署方案

第三阶段基础 时 间&#xff1a;2023年6月8日 参加人&#xff1a;全班人员 内 容&#xff1a; 企业级mysql部署方案 目录 企业级MySQL部署方案 企业级mysql部署主要步骤 Linux系统初始化设置&#xff08;做公司服务器&#xff09; 企业级MySQL高可用集群部署方案 企业…

Keysight是德MSOS604A高清晰度示波器1 GH

Keysight是德MSOS604A S系列示波器配备 6 GHz 存储器、15 英寸 XGA 电容触摸屏和 10 位模数转换器。主要特性与技术指标 1 GHz带宽和平坦的频率响应确保高信号保真度 20 GSa/s 最大采样率 10 位模数转换器&#xff08;ADC&#xff09;保证高垂直分辨率 低噪声前端&#xff…