【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. Python 嵌入式打包 (图文)

    Python嵌入式打包过程 目录 Python嵌入式打包过程 下载嵌入式包 解压和配置 安装pip和其他依赖 启动项目 python嵌入式打包:将python环境与项目代码打包到同一个文件夹中,在其他 ...

  2. 更改DataFrame列顺序

    使用pandas进行数据分析的时候,有时会由于各种需求添加了一些列.可是列的顺序并不能符合自己的期望.这个时候就需要对于列的顺序进行调整. import numpy as np import pand ...

  3. BlockingQueue家族成员一览

    最近在复习多线程的知识,必然少不了要扫描一遍JUC包下的各个类或接口,今天就先来聊一聊阻塞队列BlockingQueue: BlockingQueue是jdk1.5发布的JUC包下的一个工具类,他提供 ...

  4. zephyr的GPIOTE驱动开发记录——基于nordic的NCS

    简介: 本次测试了zephyr的中断驱动方式(GPIOTE),在这可以去看zephyr的官方文档对zephyr的中断定义,连接如下,Interrupts - Zephyr Project Docume ...

  5. 【云原生 · Kubernetes】Taint和Toleration(污点和容忍)

    个人名片: 因为云计算成为了监控工程师‍ 个人博客:念舒_C.ying CSDN主页️:念舒_C.ying Taint和Toleration(污点和容忍) 概念 添加多个tainit(污点) 使用例子 ...

  6. 新零售SaaS架构:多租户系统架构设计

    什么是多租户? 多租户是SaaS领域的特有产物,在SaaS服务中,租户是指使用SaaS系统的客户,租户不同于用户,例如,B端SaaS产品,用户可能是某个组织下的员工,但整个企业组织是SaaS系统的租户 ...

  7. (GCC) C++代码中使用#pragma GCC optimize / #pragma G++ optimize

    科学计算用优化 经过实验证明这个命令优化效果最好,把我的 1.2S 的 FFT 优化到了 0.4S使用 pragma 命令优化程序: #pragma GCC optimize("Ofast, ...

  8. java集合类 collection接口,List集合

    java集合类:collection接口,List集合 在java.util包中提供了一些集合类,集合类又被称为容器,常用的有List集合,Set集合,Map集合.下面将介绍collection接口和 ...

  9. linux开机进入grub rescue界面修复

    一.先输入ls回车,查看显示内容 如: (hd0) (hd0,msdos1) (hd0,msdos2)... 二.然后找出哪个盘安装了系统 ls (hd0,msdos1)/boot/grub/ ls( ...

  10. java面试题-线程

    简述线程.程序.进程的基本概念.以及他们之间关系是什么? 系统运行程序到停止就是一个进程创建到消亡的过程,而线程则是进程的更小单位 线程有哪些基本状态? 初始,运行中,等待,阻塞,超时,终止1 关注公 ...