首页 > 编程语言 >面向对象程序设计之链表 list 的简析(C++)

面向对象程序设计之链表 list 的简析(C++)

时间:2024-09-04 21:55:29浏览次数:7  
标签:迭代 list lt back 链表 简析 push

简介:链表是一个双向的结构,与string与vector不同的是他不支持[]访问,因为链表是由一个节点一个节点连接而成的,并不连续。我们可以在常数量级内对于链表进行插入与删除数据

1.构造函数

我们在cplusplus.com中可以查到链表总共有四种构造的方式:1.无参构造(默认构造);2.使用n个val构造;3.迭代器区间构造;4.拷贝构造

接下来让我们简单创建一个链表并对其进行遍历 

//n个val构造
list<int> lt(5, 1);
//迭代器遍历
list<int>::iterator it = lt.begin();
while (it != lt.end())
{
	cout << *it << " ";
	++it;
}
cout << endl;
//范围for遍历
for (auto e : lt)
{
	cout << e << " ";
}
cout << endl;

2.迭代器的简要了解

2.1按照功能分类

iterator:迭代器

reverse_iterator:反向迭代器

const iterator:只读迭代器

const reverse_iterator:只读反向迭代器

2.2按照性质分类 

单向迭代器:forward_list/unordered_map/unorder_set......只支持 ++ 操作

双向迭代器:list/map/set........支持 ++ 、-- 操作

随机迭代器:string/vector/deque.........支持 ++ 、-- 、+ 、-  操作

还有两种迭代器可以作为了解,他们就是只读与只写迭代器,根据箭头各种迭代器之间可以近似理解为包含关系,即若一个函数参数要求单项迭代器,那么双向迭代器的参数同样可以,但是反之则不可以

 比如如果我们使用不匹配的迭代器就有可能出错,例如库函数中的sort要求随机迭代器,因为其底层函数需要进行 - 的操作,如果是双向迭代器就无法进行该操作,就会报错 

list<int> lt(5, 1);
sort(lt.begin(), lt.end());//错误,库函数中的sort要求使用随机迭代器类型

 

3.常用接口以及注意事项 

3.1push_back

尾插函数,注意push_back只能插入单个数据,无法直接插入(1,1)这样类型的函数

//n个val构造
list<int> lt(5, 1);

lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
lt.push_back(5);
//迭代器遍历
list<int>::iterator it = lt.begin();
while (it != lt.end())
{
	cout << *it << " ";
	++it;
}
cout << endl;
//范围for遍历
for (auto e : lt)
{
	cout << e << " ";
}
cout << endl;

3.2emplace_back

尾插函数,与push_back不同的是,emplace_back可以直接插入(2,2)这样的数据

struct A
{
public:
	A(int a1 = 1,int a2 = 1)
		:_a1(a1)
		,_a2(a2)
	{}
	int _a1;
	int _a2;

};

list<A> lt;
A aa1(1, 1);
lt.push_back(aa1);
lt.push_back(A(2, 2));//匿名对象
//lt.push_back(2, 2);//报错

lt.emplace_back(aa1);
lt.emplace_back(A(2, 2));
lt.emplace_back(2, 2);//可以直接尾插

//迭代器遍历
list<int>::iterator it = lt.begin();
while (it != lt.end())
{
	cout << *it << " ";
	++it;
}
cout << endl;
//范围for遍历
for (auto e : lt)
{
	cout << e << " ";
}
cout << endl;

 3.3insert

在指定位置之前插入数据,可以使用循环实现在任意位置插入数据

list<int> lt(5, 1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
lt.push_back(5);

lt.insert(lt.begin(), 10);//在首位前插入数据

//在第k个位置之前插入数据
auto it = lt.begin();
int k = 3;
while (k--)
{
	it++;
}
lt.insert(it, 30);

//迭代器遍历
list<int>::iterator it = lt.begin();
while (it != lt.end())
{
	cout << *it << " ";
	++it;
}
cout << endl;
//范围for遍历
for (auto e : lt)
{
	cout << e << " ";
}
cout << endl;

3.4erase 

删除指定位置数据


	list<int> lt(5, 1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);
	lt.push_back(5);

	int x = 0;
	cin >> x;
	auto it = find(lt.begin(), lt.end(), x);
	//如果find没有找到就会返回第二个参数也就是lt.end()
	while (it != lt.end())
	{
		lt.erase(it);
	}

//迭代器遍历
list<int>::iterator it = lt.begin();
while (it != lt.end())
{
	cout << *it << " ";
	++it;
}
cout << endl;
//范围for遍历
for (auto e : lt)
{
	cout << e << " ";
}
cout << endl;

3.5reverse 

逆置链表

list<int> lt(5, 1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
lt.push_back(5);

lt.reverse();

//迭代器遍历
list<int>::iterator it = lt.begin();
while (it != lt.end())
{
	cout << *it << " ";
	++it;
}
cout << endl;
//范围for遍历
for (auto e : lt)
{
	cout << e << " ";
}
cout << endl;

 3.6sort

库函数中的sort函数不支持链表,所以链表自实现了一个sort函数来进行排序,默认是升序,可以使用仿函数来进行降序的调整即lt.sort(greater<int>())与lt.sort(less<int>())

list<int> lt(5, 1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
lt.push_back(5);

lt.sort();

//迭代器遍历
list<int>::iterator it = lt.begin();
while (it != lt.end())
{
	cout << *it << " ";
	++it;
}
cout << endl;
//范围for遍历
for (auto e : lt)
{
	cout << e << " ";
}
cout << endl;

3.7merge

将两个有序链表进行合并,如果将second链表合并到first链表,则second链表就会置空,其合并的原理就是取小尾插到被合并链表

list<int> first;
first.push_back(1);
first.push_back(2);
first.push_back(3);
first.push_back(4);

list<int> second;
second.push_back(10);
second.push_back(20);
second.push_back(30);
second.push_back(40);

first.merge(second);
//范围for遍历
for (auto e : first)
{
	cout << e << " ";
}
cout << endl;
//范围for遍历
for (auto e : second)
{
	cout << e << " ";
}
cout << endl;

3.8unique

去重,注意只能对有序数据去重 

list<int> lt(5, 1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
lt.push_back(5);

//范围for遍历
for (auto e : lt)
{
	cout << e << " ";
}
cout << endl;

lt.unique();

//范围for遍历
for (auto e : lt)
{
	cout << e << " ";
}
cout << endl;

3.9splice

剪切另一链表的指定数据到被粘贴链表,被剪切链表中被剪切的数据会直接删除,也可以对自身进行操作,即变化自身链表数据的顺序

list<int> first;
first.push_back(1);
first.push_back(2);
first.push_back(3);
first.push_back(4);

list<int> second;
second.push_back(10);
second.push_back(20);
second.push_back(30);
second.push_back(40);

auto it = first.begin();
it++;

first.splice(it, second);//在First链表的第一个位置之后粘贴剪切后的数据
//范围for遍历
for (auto e : first)
{
	cout << e << " ";
}
cout << endl;
//范围for遍历
for (auto e : second)
{
	cout << e << " ";
}
cout << endl;

list<int> lt(5, 1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
lt.push_back(5);
cout << endl;
//范围for遍历
for (auto e : lt)
{
	cout << e << " ";
}
cout << endl;

int k = 0;
cin >> k;
auto it = find(lt.begin(), lt.end(), k);
if(it != lt.end())
{
	lt.splice(lt.begin(), lt, it);
}
cout << endl;
//范围for遍历
for (auto e : lt)
{
	cout << e << " ";
}
cout << endl;

 

 

标签:迭代,list,lt,back,链表,简析,push
From: https://blog.csdn.net/2301_80689220/article/details/141827265

相关文章

  • 深入了解链表 list 之的模拟实现 list (C++)
    1.基本框架关于链表我们知道其是一个双向循环结构,并且由许多节点组成,各个节点之间内存空间不一定连续,每个节点均有前驱指针与后继指针,下面我们使用类模版来实现一个适用于存储大部分数据类型的链表,由下面代码我们可以看到一些基础框架与很简单的函数size返回长度与empty判断......
  • 数据结构——单链表查询、逆序、排序
    1、思维导图2、查、改、删算法//快慢排序法找中间值intmid_link(Link_t*plink){Link_Node_t*pfast=plink->phead;Link_Node_t*pslow=pfast;intm=0;while(pfast!=NULL){pfast=pfast->pnext;++m;if(m%......
  • 单向链表与双向链表
    内存泄漏:手动申请的空间没有得到及时释放,导致内存发生内存泄漏(循环)    可以使用valgrind命令判断有无发生内存泄漏快慢指针法找中间节点:链表倒置: 链表插入排序: 单向链表与双向链表区别:一、单向链表:    1.单向链表的每个节点包含两部分信息:一部分是......
  • Linkedlist源码详解
    介绍LinkedList同时实现了List接口和Deque接口,也就是说它既可以看作一个顺序容器,又可以看作一个队列(Queue),同时又可以看作一个栈(Stack)。这样看来,LinkedList简直就是个全能冠军。当你需要使用栈或者队列时,可以考虑使用LinkedList,一方面是因为Java官方已经声明不建议使用Stack类......
  • linkedlist
    data=newLinkedList[BASE];这行代码的意思是初始化一个LinkedList对象的数组。具体解释如下:数组声明:LinkedList[]表示data是一个数组,这个数组将存储LinkedList类型的对象。在这个上下文中,它将存储LinkedList<Integer>对象,用于存储整数。大小指定:newLinkedList......
  • 23合并 K 个升序链表
    我嘞个二维数组有点小夸张了哈这个题目我最开始看就回想两个有序链表的排序,但是如果这样排,那要排k次,每次排序还有相应时间复杂度,工程量之大,相当恐怖那么这个时候我们就想起来去用堆最小堆,非子叶节点小于子叶节点,可以导致根节点是最小的,那么我们只需要把所有数据全部插......
  • 关于Java链表的一些操作以及力扣原题刷刷刷——反转链表、删除链表的倒数第N个节点
    1、反转链表1.1环境准备,可以自己先尝试实现/***@AuthorMiku*@Date2024/09/0209:54*@DescriptionTODO*@Version1.0*/publicclassSolution{staticclassListNode{intval;ListNodenext;ListNode(intval){......
  • 数据结构--链表
    单向链表链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。相较于数组,链表有以下优点:逻辑结构(1)链表采用动态内存分配的方式,在内存中不连续(2)支持动态增加或者删除元素(3)需要时可以使用malloc或者new来申请内存,不用......
  • 使用Cmake-编写CMakeLists.txt 文件
    好处:a)跨平台(makefile跟平台强相关)b)cmake可以自动生成makefile编写CMakeLists.txt文件#关键主体:cmake_minimum_required(VERSION3.10)#指定最低支持的CMake版本project(FunMainVERSION1.0)#定义项目名称及版本号#添加可执行文件add_executable(${PROJECT_N......
  • 【ORACLE】listagg() 函数
    Oracle数据库中的LISTAGG函数是一个聚合函数,它用于将多个行的字符串值合并成一个单一的字符串。这对于生成报告或创建列表非常有用,例如,将同一类别的所有项合并成一个逗号分隔的字符串。语法LISTAGG(expression,delimiter)WITHINGROUP(ORDERBYcolumn)expressio......