C++ STL——list


注:原创不易,转载请务必注明原作者和出处,感谢支持!

注:内容来自某培训课程,不一定完全正确!

一 list容器

链表list是一种物理存储单元上非连续,非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。(熟悉的链表的味道)

list特性总结:
(1) 采用动态存储分配,不会造成内存浪费和溢出
(2)链表执行插入和删除十分方便,修改指针即可,不需要移动大量元素
(3)链表灵活,但是空间和时间额外耗费比较大

如图所示,C++中list实际上更像是双向链表。它所支持的常用操作也在图中列出。

链表和数组有什么区别?
(1)数组必须事先定义固定长度(元素个数),不能适应数据动态地增减的情况。当数据增加时,可能超出原先定义的元素个数;当数据减少时,造成内存浪费。
(2)链表动态地进行存储分配,可以适应数据动态地增减的情况,且可以方便地插入,删除数据元素。在数组中插入,删除数据项时,需要移动其它数据项。

1.1 list常用API

构造函数

list<T> lst;			// 对象的默认构造形式
list(beg, end);			// 将[beg, end)区间中的元素拷贝给本身
list(n, elem);			// 将n个elem元素拷贝给本身
list(const list &lst);	// 拷贝构造函数

插入和删除

push_back(elem);		// 尾部插入元素
pop_back();				// 尾部删除元素
push_front();			// 首部插入元素
pop_front();			// 首部删除元素

insert(pos, elem);		// 在pos位置插入elem元素,返回数据的位置
insert(pos, n, elem);	// 在pos位置插入n个elem元素,无返回值
insert(pos, beg, end);	// 在pos位置插入区间[beg, end)的元素,无返回值

clear();				// 清空容器
erase(beg, end);		// 删除[beg, end)区间内的数据
erase(pos);				// 删除pos位置的数据,返回下一个数据的位置
remove(elem);			// 删除容器中所有与elem匹配的元素

大小操作

size();					// 返回容器中元素个数
empty();				// 判断容器是否为空
resize(num);			// 重新指定容器的长度为num,若容器变长,则以默认值填充。如果容器变短,则超出容器长度元素将被删除
resize(num, elem);		// 重新指定容器长度为num,elem为填充的默认值

赋值操作

assign(beg, end);		// 将[beg, end)区间中的数据拷贝赋值给本身
assign(n, elem);		// 将n个elem拷贝赋值给本身
// 重载等号运算符
list &operator=(const list &lst);
swap(lst);				// 将lst与本身的元素互换

数据存取

front();		// 返回第一个元素
back();			// 返回最后一个元素

逆序和排序

reverse();		// 反转链表
sort();			// 排序

1.2 list应用案例

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

// 初始化
void Test1()
{
	list<int> lst1;
	list<int> lst2(10, 10);
	list<int> lst3(lst2.begin(), lst2.end());
	list<int> lst4(lst3);

	printList(lst4);
}


// 插入和删除
void Test2()
{
	list<int> lst;
	lst.push_back(100);
	lst.push_front(200);

	lst.insert(lst.begin(), 500);
	lst.insert(lst.end(), -100);

	list<int>::iterator pos = lst.begin();
	pos++;
	pos++;
	// 在lst.begin() + 2的位置前插入2个10
	lst.insert(pos, 2, 10);
	printList(lst);

	pos = lst.begin();
	int arr[] = { 1, 2, 3, 4, 5 };
	pos++; pos++; pos++; pos++;
	lst.insert(pos, arr, arr + sizeof(arr) / sizeof(int));
	printList(lst);

	// 删除
	lst.pop_back();
	lst.pop_front();
	printList(lst);

	lst.remove(10);
	printList(lst);

	lst.erase(lst.begin(), lst.end());
	if (lst.empty())
	{
		cout << "list is empty !" << endl;
	}
}

// 赋值
void Test3()
{
	list<int> l;
	l.assign(10, 10);

	list<int> l2;
	l2 = l;
	printList(l2);
}

// 从大到小排序
bool cmp(int a, int b)
{
	return a > b;
}

// 逆序和排序
void Test4()
{
	int arr[] = { 1, 4, 9, 5, 8, 2, 7 };
	list<int> l(arr, arr + sizeof(arr) / sizeof(int));
	printList(l);

	l.reverse();
	printList(l);

	// 这里的sort()是list的成员函数不是alogrithm里的算法
	l.sort(cmp);
	printList(l);
}

注意:算法algorithm头文件中的sort()算法只支持可随机访问的容器,而list是不支持随机访问的,所以list自己提供了sort()成员方法。

原文地址:https://www.cnblogs.com/laizhenghong2012/p/11785841.html