首页 > 其他分享 >【代码随想录】二、链表:2、设计链表

【代码随想录】二、链表:2、设计链表

时间:2024-08-16 14:50:09浏览次数:10  
标签:index 结点 cur val 代码 随想录 next 链表

部分图文参考于:代码随想录 - 707. 设计链表

这道题目设计链表的五个接口:
● 获取链表第index个节点的数值
● 在链表的最前面插入一个节点
● 在链表的最后面插入一个节点
● 在链表第index个节点前面插入一个节点
● 删除链表的第index个节点
可以说这五个接口,已经覆盖了链表的常见操作,是练习链表操作非常好的一道题目。

1.题目链接

707.设计链表

2.思路

我们引入一个虚拟头结点来进行操作(dummyHead)。
1.get(index) 获取第index个结点的值。如果索引无效,返回-1。
(1)索引越界:当index<0或是index>size-1,索引无效。
(2)获取第index个结点的值:当前结点cur指向dummyHead的next,在index=0时,即获取头结点的值(cur->val)。在index为其他值时,通过while(index--){cur = cur -> next;}将当前结点cur向后移,直到移到index处,结束while循环。

2.addAtHead(val) 头部插入结点
注意插入时的顺序:
①newNode->next = dummyHead->next;
②dummyHead->next = newNode;
image

3.addAtTail(val) 尾部插入结点
当前结点的next结点不为空时,持续向后找最后一个结点。找到后,在当前结点后插入新结点:cur -> next = newNode;

4.addAtIndex(index,val) 第index个结点前插入结点
(1)index如果大于链表长度,不会插入结点。index小于0,在头部插入结点。index等于链表长度,则该结点将附加到链表末尾。
(2)当前结点cur指向dummyHead,使用while(index--){cur = cur->next}找到index所在位置。
(3)插入结点。newNode->next = cur->next; cur->next = newNode;

2-4需要size++。

5.deleteAtIndex(index) 删除第index个结点
(1)需要判断index是否有效,index<0或index≥size无效。
(2)通过while(index--){cur=cur->next;}找到要删除的结点。
(3)删除操作:cur->next = cur->next->next;
(4)C++需要delete释放无效结点内存。

class MyLinkedList {
public:
    // 定义链表节点结构体
    struct LinkedNode {
        int val;
        LinkedNode* next;
        LinkedNode(int val):val(val), next(nullptr){}
    };

    // 初始化链表
    MyLinkedList() {
        _dummyHead = new LinkedNode(0); // 这里定义的头结点 是一个虚拟头结点,而不是真正的链表头结点
        _size = 0;
    }

    // 获取到第index个节点数值,如果index是非法数值直接返回-1, 注意index是从0开始的,第0个节点就是头结点
    int get(int index) {
        if (index > (_size - 1) || index < 0) {
            return -1;
        }
        LinkedNode* cur = _dummyHead->next;
        while(index--){ // 如果--index 就会陷入死循环
            cur = cur->next;
        }
        return cur->val;
    }

    // 在链表最前面插入一个节点,插入完成后,新插入的节点为链表的新的头结点
    void addAtHead(int val) {
        LinkedNode* newNode = new LinkedNode(val);
        newNode->next = _dummyHead->next;
        _dummyHead->next = newNode;
        _size++;
    }

    // 在链表最后面添加一个节点
    void addAtTail(int val) {
        LinkedNode* newNode = new LinkedNode(val);
        LinkedNode* cur = _dummyHead;
        while(cur->next != nullptr){
            cur = cur->next;
        }
        cur->next = newNode;
        _size++;
    }

    // 在第index个节点之前插入一个新节点,例如index为0,那么新插入的节点为链表的新头节点。
    // 如果index 等于链表的长度,则说明是新插入的节点为链表的尾结点
    // 如果index大于链表的长度,则返回空
    // 如果index小于0,则在头部插入节点
    void addAtIndex(int index, int val) {

        if(index > _size) return;
        if(index < 0) index = 0;        
        LinkedNode* newNode = new LinkedNode(val);
        LinkedNode* cur = _dummyHead;
        while(index--) {
            cur = cur->next;
        }
        newNode->next = cur->next;
        cur->next = newNode;
        _size++;
    }

    // 删除第index个节点,如果index 大于等于链表的长度,直接return,注意index是从0开始的
    void deleteAtIndex(int index) {
        if (index >= _size || index < 0) {
            return;
        }
        LinkedNode* cur = _dummyHead;
        while(index--) {
            cur = cur ->next;
        }
        LinkedNode* tmp = cur->next;
        cur->next = cur->next->next;
        delete tmp;
        //delete命令指示释放了tmp指针原本所指的那部分内存,
        //被delete后的指针tmp的值(地址)并非就是NULL,而是随机值。也就是被delete后,
        //如果不再加上一句tmp=nullptr,tmp会成为乱指的野指针
        //如果之后的程序不小心使用了tmp,会指向难以预想的内存空间
        tmp=nullptr;
        _size--;
    }

    // 打印链表
    void printLinkedList() {
        LinkedNode* cur = _dummyHead;
        while (cur->next != nullptr) {
            cout << cur->next->val << " ";
            cur = cur->next;
        }
        cout << endl;
    }
private:
    int _size;
    LinkedNode* _dummyHead;

};

● 时间复杂度: 涉及 index 的相关操作为 O(index), 其余为 O(1)。
● 空间复杂度: O(n)。

标签:index,结点,cur,val,代码,随想录,next,链表
From: https://www.cnblogs.com/Henfiu/p/18359113

相关文章

  • 【代码随想录】二、链表:1、移除链表元素
    部分图文参考于:代码随想录-203.移除链表元素。C++编程中记得要手动释放结点内存。链表操作中,可以使用原链表来直接进行删除操作,也可以设置一个虚拟头结点再进行删除操作。1.题目链接203.移除链表元素2.思路以链表1424来举例,移除元素4。如果使用C,C++编程语言的话,......
  • 【代码随想录】二、链表:理论基础
    原文链接:代码随想录-链表理论基础。1.什么是链表?链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。链表的入口节点称为链表的头结点也就是head。2.链表的类型2.1.......
  • java 调用C#语言写的dll文件代码 jar包报错 : 类文件具有错误的版本 55.0, 应为 52.0
    [ERROR]Failedtoexecutegoalorg.apache.maven.plugins:maven-compiler-plugin:3.7.0:compile(default-compile)onprojectsnowy-common:Compilationfailure[ERROR]/D:/ChengmaiDev/code/project-master/snowy-common/src/main/java/vip/xiaonuo/common/util/Commo......
  • 数据结构+单链表应用
    一、问题描述编写程序实现两个有序表的交和差,令L1=(x1,x2,x3,...,xn),L2=(y1,y2,y3,...,yn),它们是两个线性表,采用带头结点的单链表存储,请先实现单链表存储两个链表,再完成如下功能:(1)sort:将单链表的所有结点按照数据域进行递增排序,构造成有序单链表;(2)interSect:求两个......
  • 毕业设计:基于SSM的特产销售平台【代码+论文+PPT】
    全文内容包括:1、采用技术;2、系统功能;3、系统截图;4、配套内容。索取方式见文末微信号,欢迎关注收藏!一、采用技术语言:Java1.8框架:SSM数据库:MySQL5.7、8.0开发工具:IntelliJIDEA旗舰版其他:Maven3.8以上二、系统功能用户管理:负责处理用户的注册、登录、个人信息维护以及权限控......
  • 代码随想录 day31|| 56 合并区间,738 单调递增数字,968 监控二叉树
    56合并区间funcmerge(intervals[][]int)[][]int{ //思路先排序,然后按照后一个左区间和前一个右区间进行对比判断是否重叠,重叠扩充右区间 sort.Slice(intervals,func(i,jint)bool{ ifintervals[i][0]==intervals[j][0]{ returnintervals[i][1]<intervals[......
  • 迁移学习代码复现
    一、前言说来可能令人难以置信,迁移学习技术在实践中是非常简单的,我们仅需要保留训练好的神经网络整体或者部分网络,再在使用迁移学习的情况下把保留的模型重新加载到内存中,就完成了迁移的过程。之后,我们就可以像训练普通神经网络那样训练迁移过来的神经网络了。我们使用已......
  • 「代码随想录算法训练营」第三十九天 | 动态规划 part12
    115.不同的子序列题目链接:https://leetcode.cn/problems/distinct-subsequences/文章讲解:https://programmercarl.com/0115.不同的子序列.html题目难度:困难视频讲解:https://www.bilibili.com/video/BV1fG4y1m75Q/题目状态:看题解思路:动态规划数组初始化创建一个二维动......
  • 混合策略改进的蜣螂算法(IDBO)优化长短期记忆神经网络原理及matlab代码
    目录0引言1数学模型2模型对比3matlab代码3.1改进的主代码3.2IDBO-LSTM4视频讲解0引言针对DBO算法全局探索能力不足、易陷入局部最优以及收敛精度不理想等问题,多为学者提出了混合多策略改进的蜣螂优化算法(IDBO)。主要混合策略改进首先是采用混沌映射结合随机反......
  • 混合策略改进的蜣螂算法(IDBO)优化支持向量机原理及matlab代码
    目录0引言1数学模型2模型对比3matlab代码3.1改进的主代码3.2IDBO-SVM4视频讲解0引言针对DBO算法全局探索能力不足、易陷入局部最优以及收敛精度不理想等问题,多为学者提出了混合多策略改进的蜣螂优化算法(IDBO)。主要混合策略改进首先是采用混沌映射结合随机反向......