当前位置: 首页 > news >正文

C++:从0开始学习链表

        在C++中有一种很重要的数据容器:链表.

        链表内部不是连续的存储单元,而是若干非连续的数据单元,通过记录每个数据的地址,将其连接形成一种链式结构

1.链表基本概念:

(1)包含值域和指针域:

值域:该节点存的数据的值

指针域:指向下一个节点的地址

(2)一般用结构体创建

struct ListNode {int val;//值域ListNode* next;//指针域,指向下一个节点的地址//如果不写构造函数,系统默认提供一个无参构造ListNode(int x) {//构造函数用于初始化链表val = x;next = nullptr;}
};

  

2.创建链表:

一般使用new关键字在堆区创建,也可以在栈区创建,但是不推荐使用

返回值是一个地址,要用指针变量接收

int main() {ListNode* node2 = new ListNode(2);//在堆区创建,初始化值域为2cout << node2->val << endl;//2return 0;
}

  

3.链表的头节点和尾节点

初始化为空指针,空指针不能访问成员变量,使用前需要判断是否为空

ListNode* head = nullptr;//记录头节点
ListNode* tail = nullptr;//记录尾节点//使用时
if (head != nullptr) {    }

 

下面我们来创建一个链表并输入数据

输入n个数,按顺序组成链表

int n;
cin >> n;
for (int i = 0;i < n;i++) {int x;cin >> x;ListNode* node = new ListNode(x);if (head == nullptr) {//当前链表中没有节点head = node;tail = node;}else {//当前链表中有节点tail->next = node;//将原尾节点的指针域更新为指向nodetail = node;//将尾节点更新为node}
}

  

4.遍历链表

(1)链表只能从前往后遍历,不能反向遍历

(2)链表的头节点不能改变,所以需要用一个p接收头节点,并使用p进行遍历

ListNode* p = head;
while (p != nullptr) {//最后一个节点指向空,遍历到最后一个节点后,循环结束cout << p->val << " ";p = p->next;
}

  

链表的概念和创建我们已经了解了,接下来我们来学学如何使用链表

链表操作:

1.查询节点

(1)查询值等于val的节点

遍历链表,加入if条件判断

if判断可以将其输出,也可以直接退出循环

如果退出循环此时指针指向的就是等于val的节点,我们可以对其做一些处理,如修改,删除等

int main(){    int val = 3;//查询值等于3的节点ListNode* l = head;while (l != nullptr) {if (l->val == val) {cout << l->val<< endl;}l = l->next;//将l指向下一个节点}return 0;
}

(2)查询位置为n的节点

int main(){    int n = 4;ListNode* l = head;int count = 0;while (l != nullptr&&count < n-1) {count++;l = l->next;}//此时l指向位置为n的元素,然后我们将其输出cout << l->val;return 0;
}

2.插入节点

在链表中插入一个节点,我们需要知道该节点前一个节点的地址

(1)在尾部插入

//创建要插入的节点
ListNode* node1 = new ListNode(6);
//将原尾节点的next指向该节点
tail->next = node1;
//将尾节点赋值为该节点
tail = node1;

(2)在头部插入

ListNode* node2 = new ListNode(3);
//将要插入的节点挂到链表上
node2->next = head;
//修改头部指针
head = node2;

(3)在链表中间部分特定元素前插入节点

int val = 3;//在元素3之前插入节点
ListNode* node3 = new ListNode(9);
ListNode* l = head;
while (l->next) {//让l指向节点的下一个节点的值为3,这样就直接在l后插入元素就行if (l->next->val == val) {//将新节点插入到l指向节点后node3->next = l->next;l->next = node3;break;}l = l->next;
}

(4)通过下标插入特定点

通过一个count变量控制p1节点遍历完的位置(也可以理解成通过下标查询元素)

int index = 2;//在索引为2的元素前插入
ListNode* node4 = new ListNode(0);//创建一个新节点
int cnt = 0;//控制p1的位置
ListNode* p1 = head;
while (p1 && cnt < index - 1) {//让p1遍历完在索引前一位p1 = p1->next;cnt++;
}
node4->next = p1->next;
p1->next = node4;    

3.删除节点

在链表中删除一个节点,我们需要知道该节点前一个节点的地址,该节点的地址以及该节点后一个节点的地址

(1)通过val值查找需要删除的节点

int target = 3;//删除val为3的节点
ListNode* p1 = head;
//找到要删除节点之前的节点
while (p1->next) {if (p1->next->val == target) {break;//退出循环,使p1指向需要删除节点的前一个节点}
p1 = p1->next;
}
//进行节点删除
ListNode* p2 = p1->next->next;//指向要删除的元素的下一个节点
ListNode* cur = p1->next;//指向要删除的节点
p1->next = p2;//将前节点直接指向后节点
delete cur;//删除该元素节点
cur = nullptr;//将指针置为空,避免野指针问题

(2)删除头部节点

先判断一个节点是否为头部节点,如果是,直接将头节点指向下一个节点

int index = 0;//头节点
if (index == 0) {//判断是否是头节点ListNode* p3 = head;//指向头节点head = head->next;//将头节点指向下一个节点delete p3;//删除原头节点p3 = nullptr;//置空
}

        如果每次删除节点,我们都需要判断是否是头节点,这样会使代码变得复杂,所以我们使用一个通用的方法来删除节点

虚拟头节点:(使用该方法,无需判断是否是头节点)

        创建一个虚拟头节点,将其next指向头节点,使头节点变为链表中元素,然后使用方法(1)删除,最后将头节点重新指向原头节点,并删除虚拟头节点

//创建一个虚拟头节点
ListNode* vtnode = new ListNode(0);
//将其next指向头节点
vtnode->next = head;
ListNode* p = vtnode;//此时虚拟头节点是第一个节点int target = 5;//需要删除的元素
while (p->next) {if (p->next->val == target) {break;}p = p->next;
}
//删除节点
ListNode* p1 = p->next->next;
ListNode* p2 = p->next;
p->next = p1;
delete p2;
p2 = nullptr;//由于之后需要遍历数组,所以将头节点重新定义为原头节点
head = vtnode->next;
//删除创建的虚拟头节点
delete vtnode;
vtnode = nullptr;

        这种自定义结构体类型的链表的概念和基础操作我们就学完了,下一篇会带大家一起做一些关于链表的算法题

http://www.dtcms.com/a/500970.html

相关文章:

  • TPFanCtrl2,一款ThinkPad风扇控制工具
  • 辽宁地矿建设集团有限公司网站办办网官网
  • 网站建设协议书 印花税阿里巴巴网站域名注册
  • Redis的过期策略与内存淘汰机制
  • 从架构到体验:友猫社区平台的全栈技术解析与功能体系详解
  • 鸿蒙开发环境安装以及桌面应用开发
  • 网站建设博客作业蚌埠铁路建设监理公司网站
  • 计算机网络(tcp_socket )(一)
  • 湖北省建设厅网站上岗证查询立创商城
  • python学习之路(四)
  • 电商网站开发的职责建筑企业查询
  • 国外网站配色个人论坛类网站
  • 【Java 基础】核心知识点梳理
  • 做网站图片视频加载慢做网站的公司都有哪些岗位
  • 中药饮片采购平台的定义与作用是什么?
  • 【AI 学习日记】 深入解析MCP —— 从基础配置到高级应用指南
  • 网站买卖交易平台做网站需要编程?
  • 公司网站建设内容wordpress 识别二维码
  • 在淘宝上的毕设网站代做wordpress上传的图片不显示
  • 织梦网站数据库备份文件夹wordpress安装的要求
  • 医疗网站建设哪个好用郑州市网络设计公司
  • 用dz做网站怎么设置数据库远程wordpress数据库
  • 公司部门网站设计模板下载贵州网站建设服务平台
  • wordpress资源站源码请选择一个网站制作软件
  • 自己做网站想更换网址静态网页模板网站
  • 有哪些网站是可以做宣传的企业网站设计原则
  • 肤契:全域协议版 十 终章 回声协议 · 审判之日
  • 微网站开发案例深圳万户网络技术有限公司
  • MFC框架(Num29)
  • 哪些网站是wordpress网站建设肆金手指排名9