【C++链表】

使用c++重新写一遍LeetCode707设计链表

目的是熟悉c++中链表的操作

知识点

C++链表节点的实现

在c++中,一般通过结构体来定义链表的节点,也需要写构造函数(使用初始化列表)

如:

struct ListNode{
int val;
ListNode* next;
//要写构造函数
//结构体中的构造函数要用初始化列表来初始化属性
ListNode(int val) :val(val), next(nullptr){}
};

访问节点中的属性遵循结构体指针操作

即利用操作符 -> 可以通过结构体指针访问结构体属性

例如,遍历链表

		while(cur->next != nullptr){
cur = cur->next;
}

实现一个链表节点

c++中对于链表的操作均通过指针完成,例如:

//创建一个待插入的节点
ListNode* node4add = new ListNode(val);

上述代码在堆区开辟一块新内存存放一个ListNode对象,将指针node4add指向该区域

内存释放

在c++中操作节点,如果不再需要某个节点,一定要把该节点删除(释放内存)

例如删除节点的操作中,我们将待删除节点的上一个节点指向待删除节点的后一个节点,绕过了待删除节点,实现对该节点的删除

如果是其他语言,就直接操作就行了,在c++中不行

我们还需要将待删除节点保存下来,再删除释放

void deleteAtIndex(int index) {
if(index < 0 || index >= m_size){
return;
}
//将当前指针指向dummy
ListNode* cur = m_dummy;
while(index){
cur = cur->next;
index--;
}
//要先把待删除的节点用临时节点保存,以便之后进行delete操作
//如果不删除的话会报错
ListNode* tmp = cur->next;
cur->next = cur->next->next;
delete tmp;
m_size--; }

完整代码

class MyLinkedList {

public:
//要先定义一个结构体作为节点
struct ListNode{
int val;
ListNode* next;
//要写构造函数
//结构体中的构造函数要用初始化列表来初始化属性
ListNode(int val) :val(val), next(nullptr){}
}; MyLinkedList() {
//初始化(定义/实现)链表的头节点和size
//实际上这两个属于MyLinkedList类的成员属性,由于我们不想其被修改
//因此可以把它们写在private区
m_size = 0;
m_dummy = new ListNode(0);//在堆区开辟一块新内存存放一个ListNode对象,将指针m_dummy指向该区域
} int get(int index) {
if (index > (m_size - 1) || index < 0) {
return -1;
}
//将当前指针指向头节点(即dummy的下一个)
// ListNode* cur = m_dummy->next;
ListNode* cur = m_dummy;
while(index){
cur = cur->next;
index--;
}
return cur->next->val;//记得返回的是cur的下一个节点,因为最初cur指向的是dummy
//要么一开始就让cur指向dummy->next
} void addAtHead(int val) {
//创建一个待插入的节点
ListNode* node4add = new ListNode(val);
node4add->next = m_dummy->next;
m_dummy->next = node4add;
m_size++;
} void addAtTail(int val) {
//创建一个待插入的节点
ListNode* node4add = new ListNode(val);
ListNode* cur = m_dummy;
//遍历到链表末尾处
while(cur->next != nullptr){
cur = cur->next;
}
//插入新节点
cur->next = node4add;
m_size++; } // 在第index个节点之前插入一个新节点,例如index为0,那么新插入的节点为链表的新头节点。
// 如果index 等于链表的长度,则说明是新插入的节点为链表的尾结点
// 如果index大于链表的长度,则返回空
// 如果index小于0,则在头部插入节点
void addAtIndex(int index, int val) {
if(index > m_size){
return;
}else if(index < 0){
index = 0;
}
//将当前指针指向dummy
ListNode* cur = m_dummy;
//遍历到index位置
while(index){
cur = cur->next;
index--;
}
//找到插入位置之后开始插入
//创建一个待插入的节点
ListNode* node4add = new ListNode(val);
node4add->next = cur->next;
cur->next = node4add; //链表长度增加
m_size++;
} void deleteAtIndex(int index) {
if(index < 0 || index >= m_size){
return;
}
//将当前指针指向dummy
ListNode* cur = m_dummy;
while(index){
cur = cur->next;
index--;
}
//要先把待删除的节点用临时节点保存,以便之后进行delete操作
//如果不删除的话会报错
ListNode* tmp = cur->next;
cur->next = cur->next->next;
delete tmp;
m_size--; }
private:
int m_size;//声明链表长度
ListNode* m_dummy;//声明dummy头节点 }; /**
* Your MyLinkedList object will be instantiated and called as such:
* MyLinkedList* obj = new MyLinkedList();
* int param_1 = obj->get(index);
* obj->addAtHead(val);
* obj->addAtTail(val);
* obj->addAtIndex(index,val);
* obj->deleteAtIndex(index);
*/

707二刷错误点

1、忘记处理链表size

记得定义链表长度size

2、next的含义

举个例子

 void addAtIndex(int index, int val) {
if(index > m_size){
return;
}else if(index < 0){
index = 0;
}
//将当前指针指向dummy
ListNode* cur = m_dummy;
//遍历到index位置
while(index){
cur = cur->next;
index--;
}
//找到插入位置之后开始插入
//创建一个待插入的节点
ListNode* node4add = new ListNode(val);
node4add->next = cur->next;
cur->next = node4add; //链表长度增加
m_size++; }

这里node4add->next = cur->next;的意思是:

node4add节点的下一个节点指向cur的下一个节点A,此时cur->next代表的是一个节点

cur->next = node4add;的意思是:

cur的下一个节点指向node4add节点,此时cur->next表示访问cur节点的next属性并对其进行操作

3、get函数,要注意cur的指向

代码注释有说明,在用dummy节点的时候不要搞错返回对象

【C++ 数据结构:链表】二刷LeetCode707设计链表的更多相关文章

  1. LeetCode707 设计链表

    设计链表的实现.您可以选择使用单链表或双链表.单链表中的节点应该具有两个属性:val 和 next.val 是当前节点的值,next 是指向下一个节点的指针/引用.如果要使用双向链表,则还需要一个属性 ...

  2. [Swift]LeetCode707. 设计链表 | Design Linked List

    Design your implementation of the linked list. You can choose to use the singly linked list or the d ...

  3. 自己动手实现java数据结构(二) 链表

    1.链表介绍 前面我们已经介绍了向量,向量是基于数组进行数据存储的线性表.今天,要介绍的是线性表的另一种实现方式---链表. 链表和向量都是线性表,从使用者的角度上依然被视为一个线性的列表结构.但是, ...

  4. SDUT OJ 数据结构实验之链表二:逆序建立链表

    数据结构实验之链表二:逆序建立链表 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Problem Descr ...

  5. LeetCode707:设计链表 Design Linked List

    爱写bug (ID:iCodeBugs) 设计链表的实现.您可以选择使用单链表或双链表.单链表中的节点应该具有两个属性:val 和 next.val 是当前节点的值,next 是指向下一个节点的指针/ ...

  6. SDUT-2117_数据结构实验之链表二:逆序建立链表

    数据结构实验之链表二:逆序建立链表 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 输入整数个数N,再输入N个整数,按照 ...

  7. 数据结构作业——P53页算法设计题(7):原地逆转链表

    一. 题目描述: 设计一个算法,将链表中所有结点的链接方向"原地"逆转,即要求仅利用原表的存储空间,换句话说,要求算法的空间复杂度为O(1). 二.算法设计 #include< ...

  8. Leetcode707.Design Linked List设计链表

    设计链表的实现.您可以选择使用单链表或双链表.单链表中的节点应该具有两个属性:val 和 next.val 是当前节点的值,next 是指向下一个节点的指针/引用.如果要使用双向链表,则还需要一个属性 ...

  9. 数据结构和算法之单向链表二:获取倒数第K个节点

    我们在做算法的时候或多或少都会遇到这样的问题,那就是我们需要获取某一个数据集的倒数或者正数第几个数据.那么今天我们来看一下这个问题,怎么去获取倒数第K个节点.我们拿到这个问题的时候自然而然会想到我们让 ...

  10. JavaScript 版数据结构与算法(三)链表

    今天,我们要讲的是数据结构与算法中的链表. 链表简介 链表是什么?链表是一种动态的数据结构,这意味着我们可以任意增删元素,它会按需扩容.为何要使用链表?下面列举一些链表的用途: 因为数组的存储有缺陷: ...

随机推荐

  1. SQL--临时表的使用

    临时表的创建 临时表分为:本地临时表和全局临时表 通俗区分: 本地临时表:只能在当前查询页面使用,新开的查询是不能使用它的     #temp 全局临时表:不管开多少查询页面都可以使用  ##temp ...

  2. Vue3的新特性

    总概 1) 性能提升 打包大小减少 41% 初次渲染快 55%,更新渲染快 133% 内存减少 54% 使用 Proxy 代替 defineProperty 实现数据响应式 重写虚拟 DOM 的实现和 ...

  3. 👍SpringSecurity单体项目最佳实践

    SpringSecurity单体项目最佳实践 到这里,我们的SpringSecurity就已经完结啦,文章中可能有些地方不能做到全面覆盖,视频教程地址 初始项目地址 完成项目地址 1.搭建环境 建议下 ...

  4. java学习之SpringMVC拦截器开发

    0x00前言 springmvc的拦截器类似于Selvet的Filter,但是所属的操作又不一样 Spring MVC 提供了 Interceptor 拦截器机制,用于请求的预处理和后处理,也就是增强 ...

  5. MySQL 是怎么加行级锁的?为什么一会是 next-key 锁,一会是间隙锁,一会又是记录锁?

    大家好,我是小林. 是不是很多人都对 MySQL 加行级锁的规则搞的迷迷糊糊,一会是 next-key 锁,一会是间隙锁,一会又是记录锁. 坦白说,确实还挺复杂的,但是好在我找点了点规律,也知道如何如 ...

  6. golang实现一个简单的http代理

    代理是网络中的一项重要的功能,其功能就是代理网络用户去取得网络信息.形象的说:它是网络信息的中转站,对于客户端来说,代理扮演的是服务器的角色,接收请求报文,返回响应报文:对于web服务器来说,代理扮演 ...

  7. 更换K8S证书可用期

    帮助文档:https://zealous-cricket-cfa.notion.site/kubeadm-k8s-24611be9607c4b3193012de58860535e 解决: 1.安装GO ...

  8. 第2-3-6章 打包批量下载附件的接口开发-文件存储服务系统-nginx/fastDFS/minio/阿里云oss/七牛云oss

    目录 5.6 接口开发-根据文件id打包下载附件 5.6.1 接口文档 5.6.2 代码实现 5.6.3 接口测试 5.7 接口开发-根据业务类型/业务id打包下载 5.7.1 接口文档 5.7.2 ...

  9. Java Web中requset,session,application 的作用域及区别

    三者概述 requset概述: request是表示一个请求,只要发出一个请求就会创建一个request 用处:常用于服务器间同一请求不同页面之间的参数传递,常应用于表单的控件值传递. session ...

  10. 进军东南亚市场,腾讯云数据库 TDSQL 助力印尼 BNC 银行数字化转型

    腾讯云数据库在助力金融核心系统分布式替换上,已经辐射到了东南亚市场. 东南亚最大的银行之一印尼BNC银行(Bank Neo Commerce)已正式完成新核心分布式迁移,使用腾讯云数据库TDSQL后, ...