首页 > 其他分享 >2.设计链表

2.设计链表

时间:2024-08-19 21:27:42浏览次数:7  
标签:index cur val next 链表 设计 节点

. - 力扣(LeetCode)

题意:

在链表类中实现这些功能:

  • get(index):获取链表中第 index 个节点的值。如果索引无效,则返回-1。
  • addAtHead(val):在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。
  • addAtTail(val):将值为 val 的节点追加到链表的最后一个元素。
  • addAtIndex(index,val):在链表中的第 index 个节点之前添加值为 val  的节点。如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。
  • deleteAtIndex(index):如果索引 index 有效,则删除链表中的第 index 个节点。

707示例

删除链表节点: 

链表-删除节点

添加链表节点: 

链表-添加节点

这道题目设计链表的五个接口:

  • 获取链表第index个节点的数值
  • 在链表的最前面插入一个节点
  • 在链表的最后面插入一个节点
  • 在链表第index个节点前面插入一个节点
  • 删除链表的第index个节点

可以说这五个接口,已经覆盖了链表的常见操作,是练习链表操作非常好的一道题目

链表操作的两种方式:

  1. 直接使用原来的链表来进行操作。
  2. 设置一个虚拟头结点在进行操作。

下面采用的设置一个虚拟头结点(这样更方便一些,大家看代码就会感受出来)。

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://blog.csdn.net/2301_81409946/article/details/141334569

相关文章

  • C语言程序设计-[24] 程序结构与函数定义
    1、C程序基本结构。2、函数的分类。3、函数的定义。无参函数的代码示例如下:注:调用的函数都是无返回值的,所以使用了void。有参函数的代码示例如下:注1:调用的函数是有参数的,main()函数的a,b,c值分别传给了average()函数的x,y,z;注2:调用的函数是有返回值的,且返......
  • C语言程序设计-[23] 数组应用(续)
    1、输入一行字符,统计其中有多少个单词。根据以上分析,代码与结果如下:#include"stdio.h"intmain(){charc,pre,str[81];inti,n=0;gets(str);pre='';for(i=0;c=str[i];i++){ if(c!=''&&pre=='') {......
  • 单链表C语言版
        一、单链表的定义单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。 程序如下:#include<stdio.h>#include<stdlib.h>//定义链表节点结构体typedefstructNode{intdata;//数据域structNode*nex......
  • C语言程序设计(初识C语言后部分)
    代码是一门艺术,键盘是我的画笔。3.递归和迭代(循环就是一种迭代,迭代不仅仅是循环)·求n!递归方式:n!--->1(n=1);  n*(n-1)!(n>=1)#include<stdio.h>//n!-->递归方式intfac(intn){ if(n<=1) return1; else returnn*fac(n-1);}intmain(){ int......
  • springboot+vue电子商务网站的设计与实现【程序+论文+开题】-计算机毕业设计
    系统程序文件列表开题报告内容研究背景随着互联网技术的飞速发展,电子商务已成为全球经济的重要组成部分,深刻改变了人们的消费习惯与商业模式。电子商务网站作为连接商家与消费者的桥梁,不仅拓宽了市场边界,还极大提升了交易的便捷性和效率。然而,随着市场竞争的日益激烈,用户对......
  • springboot+vue电子商务平台管理系统【程序+论文+开题】-计算机毕业设计
    系统程序文件列表开题报告内容研究背景随着互联网技术的飞速发展,电子商务已成为全球经济的重要组成部分,深刻改变了人们的消费习惯与商业模式。随着市场规模的不断扩大,电子商务平台面临着前所未有的挑战与机遇。传统的管理方式已难以满足日益增长的用户需求、复杂的商品分类......
  • springboot+vue电子产品质量监督系统【程序+论文+开题】-计算机毕业设计
    系统程序文件列表开题报告内容研究背景随着科技的飞速发展,电子产品已成为现代社会不可或缺的一部分,渗透到人们生活的方方面面。然而,市场上电子产品的质量与性能参差不齐,消费者在面对琳琅满目的产品时往往难以做出明智的选择。近年来,因电子产品质量问题引发的安全事故频发,不......
  • 【系统架构设计】开发方法(一)
    【系统架构设计】开发方法(一)软件生命周期软件开发模型瀑布模型核心思想瀑布V模型缺点演化模型螺旋模型增量模型构件组装模型统一过程敏捷方法软件重用基于架构的软件设计形式化方法软件生命周期指软件自开始构思与研发到不再使用而消亡的过程。在GB8566-88(《软件工......
  • 动态表单后端设计
     动态表单通常用于收集各种不同类型的数据,这些数据可能随时间变化或根据用户的需求而变化。因此,数据库设计和接口设计需要足够灵活以适应不同的表单结构。以下是一些关于动态表单的数据库设计和接口设计的基本指导原则:数据库设计表单元数据表:form_id(表单ID)form_name(表......
  • 【2025毕设热门选题】《基于SpringBoot+Vue的毕业设计管理系统》功能规划和开题报告
    博主介绍:8年资深码农、211小硕,全网10万+粉丝。文科生转码,所以非常懂小白学习历程。java领域优质创作者,擅长小白基础课程教学和项目讲解辅导。专注于Java技术领域和大学生毕业项目实战讲解已经5年,服务10000+小白客户。技术范围:自己手撸SpringBoot、Vue、javaweb网站、小程......