C++ list容器

list是一个双向链表容器,可高效地进行插入删除元素。

他与vectordeque有着很大的区别,区别就体现在存储方式上!
vector是单端数组,deque是双端数组。

vector与deque的存储都是连续的,而list是不连续的存储!

list是通过指针方式与自己的上一个或者下一个元素连接在一起,就好比如链条一样。

如图:
在这里插入图片描述
在这里插入图片描述

而如果你想在中间某个位置插入元素的话,list会将指针指向那个元素,从而无需移动内存,提高效率!
如图:
在这里插入图片描述

list容器和vector、deque容器都是大同小异的,很多函数用法都是一样的!

list 特点:

  1. list不可以随机存取元素,所以不支持at.(position)函数与[]操作符。可以对其迭代器执行++,但是不能这样操作迭代器:it+3
  2. 使用时包含 头文件 #include <list>

定义

1. 无参数

list<int> list1;
list<double> list2;
list<Student> list3;
注意:尖括号内还可以设置指针类型或自定义类型。

2. 带参数

list<int> list4(5);	// 定义时分配五个元素的大小内存给容器,并用0赋值
list<int> list5(10, 2);	// 定义时将10个2赋值给容器
list<int> list6(list3.begin(), list3.end());	// 定义时将list5容器的全部元素赋值给list6

// 删除第一个元素
list1.pop_front();

// 删除最后一个元素
list1.pop_back();

// 头部增加
list1.push_front(9);

// 尾部增加
list1.push_back(5);

// 获取第一个元素
int Front = list1.front();

// 获取最后一个元素
int Back = list1.back();

// 对第一个元素赋值
list1.front() = 8;

// 对最后一个元素赋值
list1.back() = 8;

// 返回第一个元素的迭代器
list1.begin();

// 返回最后一个元素的下一个位置的迭代器
list1.end();

// 返回容器中倒数第一个元素的迭代器
list1.rbegin();

// 返回容器中倒数最后一个元素之后的迭代器
list1.rend();

// 返回容器中第一个元素的常量迭代器
list1.cbegin();

// 返回容器中最后一个元素之后的常量迭代器
list1.cend();

// 使用迭代器将list1的值全部赋值给list2
list2.assign(list1.begin(), list1.end());

// 使用前置++和前置–赋值(不能做 +1 操作
list2.assign(++list1.begin(), --list1.end());

// 将10个5赋值给list3
list3.assign(10, 5);

// 使用赋值运算符据重载赋值
list4 = list3;

// 交换两个容器的元素
list1.swap(list4);

// 返回容器中元素的个数
list1.size();

// 判断容器是否为空
list1.empty();

// 重新指定容器的长度,若容器变长,则以默认值0填充新的位置;如果容器变短,则末尾超出容器的长度的元素被删除
list1.resize(10);

// 重新指定容器的长度,若容器变长,则以5填充新的位置;如果容器变短,则末尾超出容器的长度的元素被删除
list1.resize(15, 5);

// 在开头位置插入一个666
list2.insert(list2.begin(), 666);

// 在第二个位置开始插入5个888
list2.insert(++list2.begin(), 5, 888);

// 在开头位置插入list1的所有元素
list2.insert(list2.begin(), list1.begin(), list1.end());

// 在最后面插入3个777
list2.insert(list2.end(), 3, 777);

// 这条表达式可以在任何位置插入元素,i是需要插入元素的位置

list<int>::iterator it = list2.begin();
for (int i=0; it != list2.end(); it++, i++) {
	if (i == 3) {
		list2.insert(it, list1.begin(), list1.end());
	}
}

// for循环逐个遍历,判断需要删除的元素

for (list<int>::iterator it = list1.begin(); it != list1.end(); ) {
	if (*it == 2) {
		it = list1.erase(it);
	} else {
		it++;
	}
}

// 删除所有元素
list1.clear();

// 删除[beg,end)区间的数据,返回下一个数据的位置
// list1.erase(beg, end);
list1.erase(++list1.begin(), --list1.end());

// 删除第二个元素
list1.erase(list1.begin());

// 删除容器中所有与参数匹配的元素
list1.remove(3);

// 将容器中的元素反序
list1.reverse();
例如:

list<int> list1;

list1.push_back(1);
list1.push_back(2);

// 反序
list1.reverse();

list<int>::iterator it = list1.begin();
for (; it != list1.end(); it++) {
	cout << *it << " ";		// 输出值为 2 1
}
cout << endl;

测试代码:

#include <iostream>
#include <Windows.h>
#include <list>

using namespace std;

// 定义
void test1(void) {
	list<int> list1;
	list<double> list2;


	// 带参的
	list<int> list3(10, 2);
	list<int> list4(list3.begin(), list3.end());

	list<int>::iterator it = list4.begin();
	for (; it != list4.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;


}

// 头尾/插入/删除
void test2(void) {
	list<int> list1;

	list1.push_back(1);
	list1.push_back(2);
	list1.push_back(3);
	list1.push_back(4);
	list1.push_back(5);

	// 删除第一个元素
	list1.pop_front();
	
	// 删除最后一个元素
	list1.pop_back();

	// 头部增加
	list1.push_front(9);

	// 尾部增加
	list1.push_back(9);

	list<int>::iterator it = list1.begin();
	for (; it != list1.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
}

// 数据存储
void test3(void) {
	list<int> list1;

	list1.push_back(1);
	list1.push_back(2);
	list1.push_back(3);
	list1.push_back(4);
	list1.push_back(5);

	// 获取第一个元素
	int Front = list1.front();

	// 获取最后一个元素
	int Back = list1.back();

	// 对第一个元素赋值
	list1.front() = 8;

	// 对最后一个元素赋值
	list1.back() = 8;

	list<int>::iterator it = list1.begin();
	for (; it != list1.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
}

// 迭代器
void test4(void) {
	list<int> list1;

	list1.push_back(1);
	list1.push_back(2);
	list1.push_back(3);
	list1.push_back(4);
	list1.push_back(5);

	// 返回第一个元素的迭代器
	list1.begin();

	// 返回最后一个元素的下一个位置的迭代器
	list1.end();

	// 返回容器中倒数第一个元素的迭代器
	list1.rbegin();

	// 返回容器中倒数最后一个元素之后的迭代器
	list1.rend();

	// 返回容器中第一个元素的常量迭代器
	list1.cbegin();

	// 返回容器中最后一个元素之后的常量迭代器
	list1.cend();

}

// 赋值
void test5(void) {
	list<int> list1, list2, list3, list4;

	list1.push_back(1);
	list1.push_back(2);
	list1.push_back(3);
	list1.push_back(4);
	list1.push_back(5);

	// 使用迭代器将list1的值全部赋值给list2
	list2.assign(list1.begin(), list1.end());

	// 使用前置++和前置--赋值(不能做 +1 操作)
	list2.assign(++list1.begin(), --list1.end());

	// 将10个5赋值给list3
	list3.assign(10, 5);

	// 使用赋值运算符据重载赋值
	list4 = list3;

	// 交换两个容器的元素
	list1.swap(list4);

	list<int>::iterator it = list1.begin();
	for (; it != list1.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
}

// list的大小
void test6(void) {
	list<int> list1;

	list1.push_back(1);
	list1.push_back(2);
	list1.push_back(3);
	list1.push_back(4);
	list1.push_back(5);

	// 返回容器中元素的个数
	list1.size();

	// 判断容器是否为空
	list1.empty();

	// 重新指定容器的长度,若容器变长,则以默认值0填充新的位置;如果容器变短,则末尾超出容器的长度的元素被删除
	list1.resize(10);

	// 重新指定容器的长度,若容器变长,则以5填充新的位置;如果容器变短,则末尾超出容器的长度的元素被删除 
	list1.resize(15, 5);

	list<int>::iterator it = list1.begin();
	for (; it != list1.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
}

// list 中间插入
void test7(void) {
	list<int> list1;
	list<int> list2(5);

	list1.push_back(1);
	list1.push_back(2);
	list1.push_back(3);
	list1.push_back(4);
	list1.push_back(5);

	// 在开头位置插入一个666
	list2.insert(list2.begin(), 666);	// 666 0 0 0 0 0 

	// 在第二个位置开始插入5个888
	list2.insert(++list2.begin(), 5, 888);	// 666 888 888 888 888 888 0 0 0 0 0 

	// 在开头位置插入list1的所有元素
	list2.insert(list2.begin(), list1.begin(), list1.end());	// 1 2 3 4 5 666 888 888 888 888 888 0 0 0 0 0 

	// 这条表达式可以在任何位置插入元素,i是需要插入元素的位置
	list<int>::iterator it = list2.begin();
	for (int i=0; it != list2.end(); it++, i++) {
		if (i == 3) {
			list2.insert(it, list1.begin(), list1.end());		// // 1 2 3 1 2 3 4 5 4 5 666 888 888 888 888 888 0 0 0 0 0 
		}
	}
	
	
	it = list2.begin();
	for (; it != list2.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
}

// list的删除
void test8(void) {
	list<int> list1;

	list1.push_back(1);
	list1.push_back(2);
	list1.push_back(3);
	list1.push_back(4);
	list1.push_back(5);

	// 删除所有元素
	list1.clear();

	//list1.erase(beg, end);  // 删除[beg,end)区间的数据,返回下一个数据的位置
	list1.erase(++list1.begin(), --list1.end());

	// 删除第二个元素
	list1.erase(list1.begin());

	// for循环逐个遍历,判断需要删除的元素
	for (list<int>::iterator it = list1.begin(); it != list1.end(); ) {
		if (*it == 2) {
			it = list1.erase(it);
		} else {
			it++;
		}
	}


	// 删除容器中所有与参数匹配的元素
	list1.remove(3);
}

// list的反序函数
void test9(void) {
	list<int> list1;

	list1.push_back(1);
	list1.push_back(2);
	list1.push_back(3);
	list1.push_back(4);
	list1.push_back(5);

	// 将容器中的元素反序
	list1.reverse();

	list<int>::iterator it = list1.begin();
	for (; it != list1.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
}

int main(void) {
	//test1();

	//test2();

	//test3();

	//test4();

	//test5();

	//test6();

	//test7();

	//test8();

	//test9();

	system("pause");
	return 0;
}

总结:
list和vec和deque这三个容器都是差不多的,只要会使用一个,那么其他两个都会了,其语法差不多。list具有更好的效率,在实际开发中也比较常用!

发布了39 篇原创文章 · 获赞 17 · 访问量 3820

猜你喜欢

转载自blog.csdn.net/cpp_learner/article/details/104672874