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

news2024/12/25 2:33:03

文章目录

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

所有的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) {
    if (_FakeNode->next != NULL) return;
    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,NULL);    // 虚假头结点
        _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) {
    if (_FakeNode->next != NULL) return;
    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[] = { 2, 3};
    int len = sizeof(arr) / sizeof(int);
    MyLinkedList m1;
    m1.ChainGenerator(arr, len);
    m1.LinkListPrint("打印链表:");
    m1.addAtHead(1);
    m1.addAtTail(5);
    m1.LinkListPrint("打印链表:");
    m1.addAtIndex(3, 4);
    m1.addAtIndex(5, 666);
    m1.LinkListPrint("打印链表:");
    m1.deleteAtIndex(5);
    m1.LinkListPrint("打印链表:");
    int val1 = m1.get(0);
    cout << "目标索引的值:" << val1 << endl;

    system("pause");
    return 0;
}

end

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

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

相关文章

jenkins用户权限管理

环境准备: 登录jenkins: http://192.168.9.190:8091/ admin asdwhl@0 一、用户权限插件安装 1、Dashboard > Manage Jenkins > Manage Plugins > Available(可选插件) 依次安装: Role-based Authorization Strategy Authorize Project

校园二手交易平台实训报告

目 录 一、设计背景 1. 需求分析 2. 课题研究的目的和意义 二、系统需求分析与开发环境 1. 系统功能需求 2. 系统界面需求 3. 开发环境 三、系统设计 四、系统测试 1. 脑模拟器测试 五、总结与展望 六、重要程序 1. LoginActivity 2. RegisterActiv…

51Proteus仿真数控0~20mA恒流源串口DAC0832数码管显示-0036

51Proteus仿真数控0~20mA恒流源串口DAC0832数码管显示-0036 Proteus仿真小实验&#xff1a; 51Proteus仿真数控0~20mA恒流源串口DAC0832数码管显示-0036 功能&#xff1a; 硬件组成&#xff1a;AT89C51单片机 6位数码管DAC0832电压输出多个按键&#xff08;设置、移动、加、…

INTERSPEECH 2023论文|基于多频带时频注意力的复调音乐旋律提取

论文题目&#xff1a; MTANet: Multi-band Time-frequency Attention Network for Singing Melody Extraction from Polyphonic Music 作者列表&#xff1a; 高虞安&#xff0c;胡英&#xff0c;王柳淞&#xff0c;黄浩&#xff0c;何亮 研究背景 复调音乐是一种具有多个声…

[PyTorch][chapter 41][卷积网络实战-LeNet5]

前言 这里结合前面学过的LeNet5 模型&#xff0c;总结一下卷积网络搭建&#xff0c;训练的整个流程 目录&#xff1a; 1&#xff1a; LeNet-5 2: 卷积网络总体流程 3&#xff1a; 代码 一 LeNet-5 LeNet-5是一个经典的深度卷积神经网络&#xff0c;由Yann LeCun在1998年提…

zabbix-agent安装

1.CentOS release 5 1-1.centos5 32位 [rootLV zabbix]# cat /etc/redhat-release CentOS release 5 (Final) [rootLV zabbix]# uname -a Linux LV 2.6.18-53.el5xen #1 SMP Mon Nov 12 03:26:12 EST 2007 i686 i686 i386 GNU/Linux确定了系统centos5 32位rpm方式安装&#…

Ubuntu18.04离线安装redis

因需要安装redis的服务器无法连接互联网&#xff0c;所以需要离线安装。首先需要下载redis的安装包&#xff0c;之后进行安装&#xff0c;在安装之前需要保证gcc&#xff0c;g&#xff0c;make等依赖包已经安装。 1. 安装gcc等依赖包 依赖包安装请参考&#xff1a; Ubuntu18…

CI570 3BSE001440R1需要电流显示和就地/远传控制

​ CI570 3BSE001440R1需要电流显示和就地/远传控制 CI570 3BSE001440R1需要电流显示和就地/远传控制 如果变频器与通讯方式与DCS系统连接&#xff0c;则只需要计算1个通讯点&#xff0c;不需要计算其他点数。 &#xff08;6&#xff09;如DCS系统外接电磁阀、指示灯、接触器等…

物联网云平台数据存储方案,这次我终于找对了

《高并发系统实战派》-- 你值得拥有 文章目录 物联网云平台存储概述为什么要做存储&#xff1f;存储的意义在哪里&#xff1f;数据存储方案设计存储数据库选型需要考虑的因素数据库选型结构化数据半结构化数据非结构化数据 案例分析第一颗栗子第二颗栗子第三颗栗子第四颗栗子 …

Web安全:vulhub 靶场搭建.(各种漏洞环境集合,一键搭建漏洞测试靶场)

Web安全&#xff1a;vulhub 靶场搭建. Vulhub是一个面向大众的开源漏洞靶场&#xff0c;无需docker知识&#xff0c;简单执行两条命令即可编译、运行一个完整的漏洞靶场镜像。让漏洞复现变得更加简单&#xff0c;让安全研究者更加专注于漏洞原理本身. 目录&#xff1a; Web安…

DLL修复工具下载,解决DLL文件问题的方法

在计算机应用程序中&#xff0c;我们经常会遇到一些错误提示&#xff0c;如“找不到.dll文件”或“无法加载.dll文件”。这些问题通常是由于缺少或损坏的DLL文件造成的。为了解决这些问题&#xff0c;我们可以借助DLL修复工具来修复和恢复DLL文件。本文将介绍什么是DLL文件&…

C# 自动更新(基于FTP)

效果 启动软件后&#xff0c;会自动读取所有的 FTP 服务器文件&#xff0c;然后读取本地需要更新的目录&#xff0c;进行匹配&#xff0c;将 FTP 服务器的文件同步到本地 Winform 界面 一、前言 在去年&#xff0c;我写了一个 C# 版本的自动更新&#xff0c;这个是根据配置文…

黑盒、白盒、灰盒,如何选择合适的模糊测试工具?

在软件开发和安全领域&#xff0c;模糊测试是一种常用技术&#xff0c;用于发现应用程序或系统中的潜在漏洞和安全弱点。选择不同的模糊测试方法将极大地影响测试的有效性和效率。本文将比较对比黑盒、白盒和灰盒模糊测试的特点和优势并提供选型指导。 模糊测试的分类 黑盒模糊…

人工智能带来的利好将继续推动Palantir股价反弹

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 Palantir的人工智能产品已经获得行业认可 Palantir&#xff08;PLTR&#xff09;成立于2003年&#xff0c;是一家专注于数据分析和人工智能的知名软件公司。其尖端产品已应用到了政府机构、企业和非营利组织等各个行业&…

华为OD机试 Java 实现【输出单向链表中倒数第k个结点】【LeetCode练习题】,附详细解题思路

一、题目描述 输入一个单向链表,输出该链表中倒数第k个结点,链表的倒数第1个结点为链表的尾指针。 链表结点定义如下: class ListNode{int value;ListNode next;public ListNode(){}public ListNode(

解决H5在native中键盘弹起影响页面交互

您好&#xff0c;如果喜欢我的文章&#xff0c;可以关注我的公众号「量子前端」&#xff0c;将不定期关注推送前端好文~ 问题描述 在native中拉起键盘再收回&#xff0c;滚动列表实际距离发生变化&#xff0c;被键盘一起弹上去了&#xff08;我这里大约是400px的样子&#xf…

使用yolox训练自己的数据集并测试

1.首先给出yolox原模型的下载地址: ​​​​​​https://github.com/bubbliiiing/yolox-pytorch 百度网盘链接给出自己完整的模型&#xff08;包括数据集以及权重文件&#xff09;&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1JNjB42u9eGNhRjr1SfD_Tw 提取码&am…

Redis和Redis可视化管理工具的下载和安装

文章目录 Redis 简介一&#xff0c;Redis 下载二&#xff0c;Redis 安装三&#xff0c;Redis 配置四&#xff0c;Redis 启动 Redis-Desktop-Manager 简介一&#xff0c;Redis-Desktop-Manager 下载二&#xff0c;Redis-Desktop-Manager 安装三&#xff0c;Redis-Desktop-Manage…

深度学习笔记之Transformer(三)自注意力机制

深度学习笔记之Transformer——自注意力机制 引言回顾&#xff1a;缩放点积注意力机制自注意力机制自注意力机制与 RNN,CNN \text{RNN,CNN} RNN,CNN的对比简单介绍&#xff1a;卷积神经网络处理序列信息的原理从计算复杂度的角度观察 位置编码 引言 上一节对注意力分数 ( Atte…

关于前端Vue脚手架的完整搭建

创建脚手架 在VSC中打开命令行&#xff0c;输入如下命令可以用于创建脚手架 Vue create <项目名称>会出现如下选项&#xff1a; 前面是选项的名称&#xff0c;括号中的是选项包含有&#xff1a; 1、Vue的版本 2、babel是用于将高版本的js转化成为低版本的js&#xff0…