4.lists(双向链表)
一.概述
是一个线性链表结构,它的数据由若干个节点构成,每一个节点都包括一个信息块(即实际存储的数据)、一个前驱指针和一个后驱指针。它无需分配指定的内存大小且可以任意伸缩,这是因为它存储在非连续的内存空间中,并且由指针将有序的元素链接起来。由于其结构的原因,list 随机检索的性能非常的不好,因为它不像vector 那样直接找到元素的地址,而是要从头一个一个的顺序查找,这样目标元素越靠后,它的检索时间就越长。检索时间与目标元素的位置成正比。
虽然随机检索的速度不够快,但是它可以迅速地在任何节点进行插入和删除操作。因为list 的每个节点保存着它在链表中的位置,插入或删除一个元素仅对最多三个元素有所影响,不像vector 会对操作点之后的所有元素的存储地址都有所影响,这一点是vector 不可比拟的。
二.特点
(1) 不使用连续的内存空间这样可以随意地进行动态操作;
(2) 可以在内部任何位置快速地插入或删除,当然也可以在两端进行push和pop 。
(3) 不能进行内部的随机访问,即不支持[ ] 操作符和vector.at() ;
Lists将元素按顺序储存在链表中,与向量(vectors)相比,它允许快速的插入和删除,但是随机访问却比较慢.。
C++标准规定:每种的容器都必须提供自己的迭代器,容器提供的一些函数以获得迭代器并以之遍历所有元素,而迭代器就是容器提供的一种遍历的方式,其本质上是一个指针。
三.常用API
| assign() | 给list赋值 |
| back() | 返回最后一个元素 |
| begin() | 返回指向第一个元素的迭代器 |
| clear() | 删除所有元素 |
| empty() | 如果list是空的则返回true |
| end() | 返回末尾的迭代器 |
| erase() | 删除一个元素 |
| front() | 返回第一个元素 |
| get_allocator() | 返回list的配置器 |
| insert() | 插入一个元素到list中 |
| max_size() | 返回list能容纳的最大元素数量 |
| merge() | 合并两个list |
| pop_back() | 删除最后一个元素 |
| pop_front() | 删除第一个元素 |
| push_back() | 在list的末尾添加一个元素 |
| push_front() | 在list的头部添加一个元素 |
| rbegin() | 返回指向第一个元素的逆向迭代器 |
| remove() | 从list删除元素 |
| remove_if() | 按指定条件删除元素 |
| rend() | 指向list末尾的逆向迭代器 |
| resize() | 改变list的大小 |
| reverse() | 把list的元素倒转 |
| size() | 返回list中的元素个数 |
| sort() | 给list排序 |
| splice() | 合并两个list |
| swap() | 交换两个list |
| unique() | 删除list中重复的元素 |
四.示例Demo
1) 使用迭代器遍历当前list元素
#include <iostream>
#include <stdlib.h>
#include <list> using namespace std;
#pragma warning(disable:4996) /*
const int arraysize = 10;
int ai[arraysize] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int *begin = ai;
int *end = ai + arraysize; // end指向的是9后面的空间
for (int *pi = begin; pi != end; ++pi)
{
cout << *pi << "";
}
*/ // 使用迭代器遍历当前链表1
void printlist(list<int> &l)
{
for (list<int>::iterator p = l.begin(); p != l.end(); ++p)
{
cout << "current item is: " << *p << endl;
}
} // 使用迭代器遍历当前链表2
void printlist2(list<int> &l)
{
list<int>::iterator current = l.begin(); // 返回第一个元素的迭代器,头指针,迭代器本质上就是一个指针
while (current != l.end()) // l.end() 代表末尾迭代器 尾指针
{
cout <<"current item is: " <<*current << endl;
current++;
} } int main() { list<int> l; for (int i = ; i < ; i++)
{
l.push_back(i + );
} cout << "current list size is: " << l.size() << endl;
printlist(l); printf("----------------------------------------\n"); list<int> s;
for (int i = ; i < ; i++)
{
s.push_front();
} list<int>::iterator s_iterator = s.begin(); // 从链表中取出链表的开头,赋值给迭代器,初始位置为0
s_iterator++;
s_iterator++;
s_iterator++; // 当前迭代器运行到3号位置(从0开始)
s.insert(s_iterator, ); // 在3号位置插入 printlist2(s); system("pause");
return ;
}
运行结果:
current list size is: 5
current item is: 1
current item is: 2
current item is: 3
current item is: 4
current item is: 5
----------------------------------------
current item is: 0
current item is: 0
current item is: 0
current item is: 5
current item is: 0
current item is: 0
current item is: 0
current item is: 0
current item is: 0
current item is: 0
current item is: 0
2) 链表元素为结构体或结构体指针
#include <iostream>
#include <stdlib.h>
#include <list> using namespace std;
#pragma warning(disable:4996) struct Teacher {
char name[];
int age;
}; // 使用迭代器遍历当前链表
void printlist(list<Teacher*> &l)
{
for (list<Teacher*>::iterator p = l.begin(); p != l.end(); ++p)
{
Teacher *teacher = *p;
cout << "Teacher, name is: " << teacher->name << ", age is: " << teacher->age << endl;
}
} // 使用迭代器遍历当前链表
void printlist2(list<Teacher> &l)
{
list<Teacher>::iterator current = l.begin(); // 返回第一个元素的迭代器,头指针,迭代器本质上就是一个指针
while (current != l.end()) // l.end() 代表末尾迭代器 尾指针
{
Teacher teacher = *current;
cout << "Teacher, name is: " << teacher.name << ", age is: " << teacher.age << endl;
current++;
} } int main() { Teacher t1, t2, t3;
strcpy(t1.name,"jack");
t1.age = ;
strcpy(t2.name,"mike");
t2.age = ;
strcpy(t3.name,"tom");
t3.age = ; list<Teacher> l;
l.push_back(t1);
l.push_back(t2);
l.push_back(t3); printlist2(l); printf("------------------指针元素-------------------\n");
list<Teacher *> m;
m.push_back(&t1);
m.push_back(&t2);
m.push_back(&t3); printlist(m); system("pause");
return ;
}
运行结果:
Teacher, name is: jack, age is: 11
Teacher, name is: mike, age is: 22
Teacher, name is: tom, age is: 33
------------------指针元素-------------------
Teacher, name is: jack, age is: 11
Teacher, name is: mike, age is: 22
Teacher, name is: tom, age is: 33
4.lists(双向链表)的更多相关文章
- [DT] 数据结构术语中英文对照
数据结构术语中英文对照 数据 Data 数据元素 Data element 数据项 Data item 数据结构 Data structure 逻辑结构 Logical structure 数据类型 ...
- UVA 12657 Boxes in a Line 双向链表
题目连接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=47066 利用链表换位置时间复杂度为1的优越性,同时也考虑到使用实际 ...
- 深入浅出Redis04使用Redis数据库(lists类型)
一 lists类型及操作 List是一个链表结构,主要功能是push,pop,获取一个范围的所有值等等,操作中key理解为链表的名字. Redis的list类型其实就是一个每个子元素都是sring类 ...
- XOR双向链表
这是一个数据结构.利用计算机的的位异或操作(⊕),来降低双向链表的存储需求. ... A B C D E ... –> next –> next –> next –> < ...
- 【一天一道LeetCode】#160. Intersection of Two Linked Lists
一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Write a ...
- [LeetCode] Flatten a Multilevel Doubly Linked List 压平一个多层的双向链表
You are given a doubly linked list which in addition to the next and previous pointers, it could hav ...
- 4、数据类型二:Lists
1.关于list的组织形式 列表数据类型(Lists)可以存储一个有序的字符串列表,常用的操作时向列表两段添加元素,或者获取列表的某一个片段.列表类型的底层实现是一个双向链表(double linke ...
- CS61B sp2018笔记 | Lists
Lists csdn同作者原创地址 1. IntLists 下面我们来一步一步的实现List类,首先你可以实现一个最简单的版本: public class IntList { public int ...
- LeetCode 430:扁平化多级双向链表 Flatten a Multilevel Doubly Linked List
您将获得一个双向链表,除了下一个和前一个指针之外,它还有一个子指针,可能指向单独的双向链表.这些子列表可能有一个或多个自己的子项,依此类推,生成多级数据结构,如下面的示例所示. 扁平化列表,使所有结点 ...
随机推荐
- 【mybatis】mybatis多表联查,存在一对多关系的,实体中使用List作为字段接收查询结果的写法
实体如下: IntegralGoods 积分商品 IntegralGoodsImg 积分商品图片 ShelfLog 积分商品自动上架记录 IntegralGoods :IntegralGoodsIm ...
- Controller和RestController的区别
1. Controller, RestController的共同点 都是用来表示Spring某个类的是否可以接收HTTP请求 2. Controller, RestController的不同点 @C ...
- iOS:quartz2D绘图(画一些简单的图形,如直线、三角形、圆、矩形、文字等)
前一篇几乎已经详细介绍了Quartz2D的所有知识,这一篇以及后面就不废话了,主要是用具体的实例来演示绘图效果. 这里我们先来绘制一些简单的图形(如直线.三角形.圆.矩形.文字.图像),它有两种方式可 ...
- python scikit-learn选择正确估算器
下图摘自官方文档 链接 http://scikit-learn.org/stable/tutorial/machine_learning_map/index.html
- 在做了 BasePage 时: 只有在配置文件或 Page 指令中将 enableSessionState 设置为 true 时,才能使用会话状态。还请确保在应用程序配置的 / / 节中包括
摘自: http://lichengguizy.blog.163.com/blog/static/11771858620122342749552/ 只有在配置文件或 Page 指令中将 enableS ...
- 教你用webgl快速创建一个小世界
收录待用,修改转载已取得腾讯云授权 作者:TAT.vorshen Webgl的魅力在于可以创造一个自己的3D世界,但相比较canvas2D来说,除了物体的移动旋转变换完全依赖矩阵增加了复杂度,就连生成 ...
- 记一次vue2路由参数传递this指针问题
需要船体一个data()内的对象到另一个页面. <player-card v-for="(note, key) in sortedtNodes" :imgurl=" ...
- Android 常见内存泄漏的解决方式
在Android程序开发中.当一个对象已经不须要再使用了,本该被回收时.而另外一个正在使用的对象持有它的引用从而导致它不能被回收.这就导致本该被回收的对象不能被回收而停留在堆内存中,内存泄漏就产生了. ...
- TestNG 四 测试方法之工厂
工厂允许你动态的创建测试.例如,假设你需要创建一个测试方法,并用它来多次访问一个web页面,而且每次都带有不同的参数: public class TestWebServer { @Test(param ...
- FPS计算New
using UnityEngine; using System.Collections; public class CarGUI : MonoBehaviour { private const flo ...