数据结构前导课 | 7 更进一步——STL库之List链表

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构前导课 | 7 更进一步——STL库之List链表相关的知识,希望对你有一定的参考价值。



戳一戳!和我一起走进信息学的世界

导读

信息学能够有助于孩子未来工作发展,提升孩子的综合能力。


这一期课,我们承上启下,简单复习信息学所有C++的知识体系,讲解一部分初赛和复赛的知识;然后就从顺序表和链表,开始一步一步走进数据结构的世界!


前一节课,我们学习了链表的相关概念,相关知识,自己实现了一些重要操作,这节课,我们一起来看一下如何使用STL库中的自带链表实现相关操作。

往期回顾

【NOIP竞赛/CSP认证】

▶  赛前必看!信息学名师带你复习NOIP竞赛初赛及CSP认证初赛


【信息学精华帖】

▶  收藏!交流会内容全公开,让你陪孩子更好地学习信息学

▶  信息学的万般好处!附C++必备基础知识总结

▶  信息学提高班知识体系详解与家长常见问题解答!让孩子赢在提高班学习的起跑线!

▶  再回首,最全提高班知识总结,做更优秀的自己!


【数据结构前导课】

▶  1 温故知新——一篇文章领略信息学C++知识结构

▶  2 披荆斩棘——只学C++,可以做哪些竞赛题

▶  3 运筹帷幄——一篇文章,让指针学起来也很简单!

▶  4 初试锋芒——顺序表写起来也很简单

▶  5 小试牛刀——STL库之vector数组

▶  6 触类旁通——链表基本理论与信息学竞赛必考点


【C++提高班教程】

▶  C++强化 | 01 新学期再出发!温故知新!

▶  C++强化 | 02 继续前行,三大结构终极介绍

▶  C++强化 | 03 一维数组入门

▶  C++强化 | 04 数组越界

▶  C++强化 | 05 一维数组经典应用

▶  C++强化 | 06 一篇文章带你掌握字符数组

▶  C++强化 | 07 二维数组

▶  C++强化 | 08 二维数组经典案例

▶  C++强化 | 09 一篇文章带你探索函数的奥秘

▶  C++强化 | 10 函数进阶必备

▶  C++强化 | 11 这样学递归,才不会觉得难

▶  C++强化 | 12 格式化输入输出与文件操作

▶  ​​C++强化 | 13 结构体入门

  ​​C++强化 | 14 结构体进阶


【C++基础班教程】

▶  C++总结 | 01 程序的世界

▶  C++总结 | 02 输出、换行与注释

▶  ​C++总结 | 03 变量定义、赋值与运算​

▶  ​C++总结 | 04 算术运算符与赋值运算符​

▶  ​C++总结 | 05 cin语句​

▶  ​C++总结 | 06 程序中的数据类型​

▶  ​C++总结 | 07 数据类型补充​

▶  ​C++总结 | 08 顺序结构​

▶  ​C++总结 | 09 if 和 if-else​

▶  C++总结 | 10 if嵌套与逻辑运算符

▶  C++总结 | 11 开关语句switch-case

▶  C++总结 | 12 for循环及其应用

▶  C++总结 | 13 数据范围与数据类型

▶  C++总结 | 14 break与continue

▶  C++总结 | 15 while与do-while

▶  C++总结 | 16 循环嵌套及其应用 



1 Vector数组复习

前面我们讲了Vector数组,Vector数组是一个STL库中的比较基础的结构,和Vector数组相对应的结构有两个,一个是array,也就是我们的普通数组,另外一个是我们今天要讲的!


为了能够让大家更好地理解今天要讲的内容,我们要先来复习一下Vector数组。

1 Vector数组理论复习

Vector数组对应的数据结构是顺序表。顺序表可以根据索引直接访问数据,访问数据非常方便,但是如果我们想插入或者删除数据可能需要移动大量元素。

2 Vector数组基本操作复习

首先我们学了几种定义以及初始化方法:


vector<int> primes;
vector<int> primes 2, 3, 5, 7, 11, 13, 17, 19;
vector<int> L1(20); //初始化L1有20个元素,每个元素默认0
vector<double> L2(20, 1.0); //初始化L2有20个元素,每个元素默认1.0


Vector我们主要学习了如下操作:


操作

含义

clear()

将顺序表置空

empty()

判断顺序表是否为空

capacity()

获取顺序表容量

size()

获取顺序表长度

insert()

插入元素

erase()

删除元素


2 链表复习

接下来我们又学习了链表。

1 链表理论复习

顺序表插入或者删除数据需要移动大量元素,链表的引入解决了这个问题,如果想插入或者删除某个元素,只需要修改对应的指针即可,不需要移动元素。


当然,链表只是插入和删除元素时候比顺序表更优,但是在其他方面,可能不如顺序表,我们下节课会着重说明顺序表和链表的对比。

2 链表插入与删除操作

我们着重学习了链表的插入和删除操作:


例如在单链表中,在节点p之后插入一个元素代码如下:


struct LinkList
int data;
LinkList *next;
;

int insertList(LinkList *&p, LinkList *&q)
q->next = p->next;
p->next = q;
return 0;


在双向链表中,在节点p之前插入一个元素代码如下:


struct TwoWayLinkList
int data;
TwoWayLinkList *llink,rlink;
;

int insertTowWayList(TwoWayLinkList *&p, TwoWayLinkList *&q)
p->llink->rlink = q;
q->llink = p->llink;
p->llink = q;
q->rlink = p;
return 0;


3 List链表必备操作

复习完上面的内容我们就可以走进今天的list链表了。

1 list链表介绍

list是STL库中自带的链表,list是一个双向链表,符合我们学的链表的特征——插入和删除不需要移动元素。


list链表结构如下:


数据结构前导课


2 list链表定义与初始化

我们先来看一下list链表的定义和初始化。


首先,我们需要用到list链表的头文件:


#include <list>
using namespace std;


创建一个list链表和vector数组很类似,我们使用list创建一个存放整数类型数据的链表:


list<int> L; //使用list创建一个链表L。


上面的只是简单地创建,没有初始化。我们还有如下创建和初始化方法:


list<int> L1(10); //创建一个包含10个整型元素的链表,每个元素默认为0 
list<int> L2 1,2,3,4,5,6; //创建一个包含6个int类型数据的链表,数据为1-6
list<double> L3(10, 0.2); //创建一个包含10个double类型数据的链表,每个元素都为0.2


我们也可以使用普通数组来构建list链表:


int a[10] = 1,2,3,4,5,6,7,8,9,10; 
list<int> L4(a, a+10);


除此之外,大家有兴趣可以自己深入研究。

3 list链表常用操作汇总

接下来我们一起看一下list链表的常用操作:


操作

含义

clear()

将链表置空

empty()

判断链表是否为空

size()

获取链表长度

resize()

调整链表大小

sort()

对链表元素进行排序

insert()

插入元素

erase()

删除元素

push_front()

在链表头部添加元素

push_back()

在链表尾部添加元素

pop_front()

在链表头部删除元素

pop_back()

在链表尾部删除元素


访问链表数据不能像顺序表那样通过索引来访问,要通过STL库中的迭代器去访问。大家可以简单将迭代器理解为指针


我们可以直接获取链表的开头和结尾的迭代器:


L4.begin(); //begin迭代器相当于指向链表中第一个元素的指针;
L4.end(); //end迭代器相当于指向链表中最后一个元素后一个位置的指针;指向位置的数据为空。


我们可以通过如下方式访问数据:


list<int> L41,2,3,4,5;
cout<<*L4.begin()<<endl;
cout<<*(--L4.end())<<endl;


迭代器支持++和--运算,但是++和--要写在迭代器的前面


我们想要访问整个链表的所有数据可以通过如下方式访问:


#include <iostream>
#include <list>
using namespace std;
int main()

list<int> L41,2,3,4,5;

auto p = L4.begin();
while (p!=L4.end())

cout << *p << " ";
++p;

return 0;


4 list链表简单应用

我们一起来来应用一下上面的代码。


首先我们先写好整个代码框架:


#include <iostream>
#include <list>
using namespace std;
int main()


return 0;


我们创建一个空的链表,然后不断从尾部添加新的整型数据,例如我们需要添加五个。添加的数据如下:


1,2,3,4,5


代码如下:


list<int> L;
int num;
for(int i = 0;i<5;i++)
cin>>num;
L.push_back(num); //将数据从尾部附加到链表中


我们可以获取链表的长度:


cout<<"当前链表的长度为"<<L.size()<<endl;


我们可以插入、删除数据,然后查看操作完后的链表数据:


L.push_front(0); //从头部插入数据0;
L.pop_back(); //将尾部数据删除 即5
L.insert(L.begin() , -1); //在头部插入数据-1
L.insert(L.end() , 6); //在尾部插入一个数据6
L.erase(L.begin()); //删除头部数据 即-1
auto p = L.begin();
while (p!=L.end()) //遍历所有数据

cout << *p << " ";
++p;


我们可以清空链表,判读链表是否为空:


L.clear();
if(L.empty()) cout<<"\\n当前链表为空\\n";
else cout<<"\\n当前链表不为空\\n";


我们还可以对链表进行排序,我们先输入五个乱序的数据,然后排序:


for(int i = 0;i<5;i++)
cin>>num;
L.push_back(num); //将数据从尾部附加到链表中

L.sort(); //对链表进行从小到大排序
p = L.begin();
while (p!=L.end()) //遍历所有数据

cout << *p << " ";
++p;


所有代码写到一起执行结果如下:


数据结构前导课


4 作业

本节课的作业,就是复习上面的所有知识,并完成下面两道题目!

1 找最值

使用list定义一个链表,输入如下数据,输出最大值和最小值;


输入输出说明:


【输入】
两行,每行数据大于-1000,小于1000
第一行一个整数n,表示输入数据的个数;
第二行n个整数,表示n个输入的数据
【输出】
一行两个整数,第一个整数为最大值,第二个整数为最小值


输入输出示例:


【输入示例】
10
1 2 3 4 5 -6 7 8 92 -100
【输出示例】
92 -100




AI与区块链技术

数据结构前导课

长按二维码关注

以上是关于数据结构前导课 | 7 更进一步——STL库之List链表的主要内容,如果未能解决你的问题,请参考以下文章

STL库之集合基本使用方法

STL库之map映射基础知识

我为同学解难题⑬C++程序设计第6期:STL标准库之map容器

boost库之异常处理

C++--第23课 - STL简介

存储库之MongoDB