【1】list简介

实质上,list容器就是一个双向链表,可以高效地进行插入、删除操作。

【2】list链表常用方法

(1)构造、赋值、清空、删除、插入、判空等

应用示例代码如下:

 #include <list>
#include <iostream>
using namespace std; // 打印链表数据信息
void print (const list<int> & tempList)
{
// cbegin 返回指向第一个元素的迭代器
// cend 返回指向最后一个元素之后位置的迭代器
list<int>::const_iterator cIter = tempList.cbegin();
for (; cIter != tempList.cend(); ++cIter)
{
cout << (*cIter) << " ";
}
cout << endl;
} void main()
{
// 构造函数(默认构造函数)
list<int> myList1; // 构造函数(构建一个list,有10个元素,每个元素值都是10)
list<int> myList2(, );
print(myList2); // 拷贝构造函数
list<int> myList3(myList2);
print(myList3); // 由区间内的值初始化list
int nArrayA[] = {, , , , };
list<int> myList4(nArrayA, nArrayA + );
print(myList4); // 赋值assign(input_iterator start, input_iterator end);
myList1.assign(nArrayA, nArrayA + );
print(myList1); // 赋值assign(size_type num, const Type & val);
myList1.assign(, );
print(myList1); // 返回对最后一个元素的引用
cout << myList4.back() << endl; // 返回对第一个元素的引用
cout << myList4.front() << endl; // 清空链表clear
myList4.clear();
cout << myList4.empty() << endl; // 删除元素erase(iterator pos)
list<int>::iterator iter = myList1.begin();
for (; iter != myList1.end(); )
{
myList1.erase(iter++);
}
cout << myList1.empty() << endl; // 删除元素erase(iterator start, iterator end)
myList3.erase(myList3.begin(), myList3.end());
cout << myList3.empty() << endl; // 插入元素insert(iterator pos, const TYPE& val)
myList1.insert(myList1.begin(), );
print(myList1); // 插入元素insert(iterator pos, size_type num, const TYPE &val)
myList1.insert(myList1.begin(), , );
print(myList1); // 插入元素insert(iterator pos, input_iterator start, input_iterator end)
int nArrayB[] = {, , , };
myList1.insert(myList1.begin(), nArrayB, nArrayB + );
print(myList1); system("pause");
} // run out:
/*
10 10 10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10 10 10
10 20 30 40 50
10 20 30 40
100 100 100 100 100 100 100 100 100 100
50
10
1
1
1
110
23 23 23 23 23 23 23 23 23 23 110
7 8 9 10 23 23 23 23 23 23 23 23 23 23 110
请按任意键继续. . .
*/

(2)merge方法

请看如下最常见的崩溃代码:

代码1:链表1无序,链表2无序。

 #include <list>
#include <iostream>
using namespace std; // 打印链表数据信息
void print (const list<int> & tempList)
{
// cbegin 返回指向第一个元素的迭代器
// cend 返回指向最后一个元素之后位置的迭代器
list<int>::const_iterator cIter = tempList.cbegin();
for (; cIter != tempList.cend(); ++cIter)
{
cout << (*cIter) << " ";
}
cout << endl;
} void main()
{
// 构造函数(默认构造函数)
list<int> myList1, myList2;
// 赋值
myList1.assign(, );
// 插入元素
int nArrayA[] = {, , , , };
myList1.insert(myList1.begin(), nArrayA, nArrayA + );
// 追加元素
for (int i = ; i < ; ++i)
{
myList1.push_back(i + );
}
cout << "打印链表1的数据:" << endl;
print(myList1); myList2.push_back();
myList2.push_back();
myList2.push_back();
myList2.push_back();
myList2.push_back();
cout << "打印链表2的数据:" << endl; print(myList2); myList1.merge(myList2);
cout << "合并后,打印链表1的数据:" << endl;
print(myList1);
cout << "合并后,打印链表2的数据:" << endl;
print(myList2); system("pause");
}

运行结果如下图:

代码2:链表1无序,链表2升序。

 #include <list>
#include <iostream>
using namespace std; // 打印链表数据信息
void print (const list<int> & tempList)
{
// cbegin 返回指向第一个元素的迭代器
// cend 返回指向最后一个元素之后位置的迭代器
list<int>::const_iterator cIter = tempList.cbegin();
for (; cIter != tempList.cend(); ++cIter)
{
cout << (*cIter) << " ";
}
cout << endl;
} void main()
{
// 构造函数(默认构造函数)
list<int> myList1, myList2;
// 赋值
myList1.assign(, );
// 插入元素
int nArrayA[] = {, , , , };
myList1.insert(myList1.begin(), nArrayA, nArrayA + );
// 追加元素
for (int i = ; i < ; ++i)
{
myList1.push_back(i + );
}
cout << "打印链表1的数据:" << endl;
print(myList1); myList2.push_back();
myList2.push_back();
myList2.push_back();
myList2.push_back();
myList2.push_back();
cout << "打印链表2的数据:" << endl; print(myList2); myList1.merge(myList2);
cout << "合并后,打印链表1的数据:" << endl;
print(myList1);
cout << "合并后,打印链表2的数据:" << endl;
print(myList2); system("pause");
}

运行结果如下图:

代码3:链表1升序,链表2降序。

 #include <list>
#include <iostream>
using namespace std; // 打印链表数据信息
void print (const list<int> & tempList)
{
// cbegin 返回指向第一个元素的迭代器
// cend 返回指向最后一个元素之后位置的迭代器
list<int>::const_iterator cIter = tempList.cbegin();
for (; cIter != tempList.cend(); ++cIter)
{
cout << (*cIter) << " ";
}
cout << endl;
} void main()
{
// 构造函数(默认构造函数)
list<int> myList1, myList2;
// 赋值
myList1.assign(, );
// 插入元素
int nArrayA[] = {, , , , };
myList1.insert(myList1.end(), nArrayA, nArrayA + );
// 追加元素
for (int i = ; i < ; ++i)
{
myList1.push_back(i + );
}
cout << "打印链表1的数据:" << endl;
print(myList1); myList2.push_back();
myList2.push_back();
myList2.push_back();
myList2.push_back();
myList2.push_back();
cout << "打印链表2的数据:" << endl; print(myList2); myList1.merge(myList2);
cout << "合并后,打印链表1的数据:" << endl;
print(myList1);
cout << "合并后,打印链表2的数据:" << endl;
print(myList2); system("pause");
}

运行结果如下图:

代码4:链表1降序,链表2降序。

 #include <list>
#include <iostream>
using namespace std; // 打印链表数据信息
void print (const list<int> & tempList)
{
// cbegin 返回指向第一个元素的迭代器
// cend 返回指向最后一个元素之后位置的迭代器
list<int>::const_iterator cIter = tempList.cbegin();
for (; cIter != tempList.cend(); ++cIter)
{
cout << (*cIter) << " ";
}
cout << endl;
} void main()
{
// 构造函数(默认构造函数)
list<int> myList1, myList2;
// 追加元素
for (int i = ; i > ; --i)
{
myList1.push_back(i + );
}
cout << "打印链表1的数据:" << endl;
print(myList1); myList2.push_back();
myList2.push_back();
myList2.push_back();
myList2.push_back();
myList2.push_back();
cout << "打印链表2的数据:" << endl; print(myList2); myList1.merge(myList2);
cout << "合并后,打印链表1的数据:" << endl;
print(myList1);
cout << "合并后,打印链表2的数据:" << endl;
print(myList2); system("pause");
}

运行结果如下图:

代码5:链表1升序,链表2升序。

 #include <list>
#include <iostream>
using namespace std; // 打印链表数据信息
void print (const list<int> & tempList)
{
// cbegin 返回指向第一个元素的迭代器
// cend 返回指向最后一个元素之后位置的迭代器
list<int>::const_iterator cIter = tempList.cbegin();
for (; cIter != tempList.cend(); ++cIter)
{
cout << (*cIter) << " ";
}
cout << endl;
} void main()
{
// 构造函数(默认构造函数)
list<int> myList1, myList2;
// 赋值
myList1.assign(, );
// 插入元素
int nArrayA[] = {, , , , };
myList1.insert(myList1.end(), nArrayA, nArrayA + );
// 追加元素
for (int i = ; i < ; ++i)
{
myList1.push_back(i + );
}
cout << "打印链表1的数据:" << endl;
print(myList1); myList2.push_back();
myList2.push_back();
myList2.push_back();
myList2.push_back(3);
myList2.push_back();
cout << "打印链表2的数据:" << endl; print(myList2); myList1.merge(myList2);
cout << "合并后,打印链表1的数据:" << endl;
print(myList1);
cout << "合并后,打印链表2的数据:" << endl;
print(myList2); system("pause");
}

运行结果如下图:

经过查资料及源码,发现问题是:

list链表合并merge方法注意事项:

1、合并的两个链表必须均默认升序的。即合并之前,两个链表就应该是由小到大顺序排列的。

2、合并完成后,被合并链表(myList2)数据元素被清空。

3、默认是按升序合并。比如上例4,若想按降序进行合并,需要指定降序。

修改后,如下代码:

 #include <list>
#include <iostream>
using namespace std; // 打印链表数据信息
void print (const list<int> & tempList)
{
// cbegin 返回指向第一个元素的迭代器
// cend 返回指向最后一个元素之后位置的迭代器
list<int>::const_iterator cIter = tempList.cbegin();
for (; cIter != tempList.cend(); ++cIter)
{
cout << (*cIter) << " ";
}
cout << endl;
} void main()
{
// 构造函数(默认构造函数)
list<int> myList1, myList2;
// 追加元素
for (int i = ; i > ; --i)
{
myList1.push_back(i + );
}
cout << "打印链表1的数据:" << endl;
print(myList1); myList2.push_back();
myList2.push_back();
myList2.push_back();
myList2.push_back();
myList2.push_back();
cout << "打印链表2的数据:" << endl; print(myList2); myList1.merge(myList2, greater<int>());
cout << "合并后,打印链表1的数据:" << endl;
print(myList1);
cout << "合并后,打印链表2的数据:" << endl;
print(myList2); system("pause");
}

按降序进行合并。前提必须两个链表均为降序有序排列。

(3)remove方法。删除链表中所有值为val的元素。

 #include <list>
#include <iostream>
using namespace std; // 打印链表数据信息
void print (const list<int> & tempList)
{
// cbegin 返回指向第一个元素的迭代器
// cend 返回指向最后一个元素之后位置的迭代器
list<int>::const_iterator cIter = tempList.cbegin();
for (; cIter != tempList.cend(); ++cIter)
{
cout << (*cIter) << " ";
}
cout << endl;
} void main()
{
// 构造函数(默认构造函数)
list<int> myList1;
myList1.assign(, );
myList1.insert(myList1.end(), , );
for (int i = ; i > ; --i)
{
myList1.push_back();
}
for (int i = ; i < ; ++i)
{
myList1.push_front(i + );
}
cout << "打印链表的数据:" << endl;
print(myList1); cout << "删除12后,打印链表数据:";
myList1.remove();
print(myList1); cout << "删除34后,打印链表数据:";
myList1.remove();
print(myList1); system("pause");
} // run out:
/*
打印链表的数据:
19 18 17 16 15 12 12 12 34 34 34 12 12 12 12 12
删除12后,打印链表数据:19 18 17 16 15 34 34 34
删除34后,打印链表数据:19 18 17 16 15
请按任意键继续. . .
*/

(4)remove_if方法。用一元函数判断是否删除元素,若函数返回true,则删除该元素。

应用示例代码如下:

 #include <list>
#include <iostream>
using namespace std; // 打印链表数据信息
void print (const list<int> & tempList)
{
list<int>::const_iterator cIter = tempList.cbegin();
for (; cIter != tempList.cend(); ++cIter)
{
cout << (*cIter) << " ";
}
cout << endl;
} bool IsDel (int i)
{
return ((i % ) == );
} void main ()
{
int myInts[] = {, , , , , , , , , };
list<int> myList(myInts, myInts + ); cout << "打印链表数据元素:" << endl;
print(myList);
myList.remove_if(IsDel);
cout << "删除(val % 2 == 1)后打印链表数据元素:" << endl;
print(myList); system("pause");
} // run out:
/*
打印链表数据元素:
1 2 3 4 5 6 7 8 9 10
删除(val % 2 == 1)后打印链表数据元素:
2 4 6 8 10
请按任意键继续. . .
*/

(5)unique方法。移除重复元素。

 #include <list>
#include <iostream>
using namespace std; // 打印链表数据信息
void print (const list<int> & tempList)
{
list<int>::const_iterator cIter = tempList.cbegin();
for (; cIter != tempList.cend(); ++cIter)
{
cout << (*cIter) << " ";
}
cout << endl;
} void main()
{
list<int> myList;
myList.assign(, );
for (int i = ; i < ; ++i)
{
myList.push_front(i + );
}
for (int i = ; i < ; ++i)
{
myList.push_back( + i);
}
myList.insert(myList.end(), , ); print(myList);
myList.unique(); // 移除重复元素
print(myList); system("pause");
} // run out:
/*
6 5 4 3 2 100 100 100 100 100 10 11 12 13 14 45 45 45 45 45
6 5 4 3 2 100 10 11 12 13 14 45
请按任意键继续. . .
*/

(6)splice 粘接方法的三种方式

应用示例代码如下:

 #include <list>
#include <iostream>
using namespace std; // 打印链表数据信息
void print (const list<int> & tempList)
{
list<int>::const_iterator cIter = tempList.cbegin();
for (; cIter != tempList.cend(); ++cIter)
{
cout << (*cIter) << " ";
}
cout << endl;
} void main()
{
list<int> myList1, myList2, myList3, myList4;
myList1.assign(, );
myList2.push_front();
cout << "打印myList2的数据:" << endl;
print(myList2);
cout << "打印myList1的数据:" << endl;
print(myList1);
// 粘接方法1:splice(iterator pos, list& lst)
// 将myList1链表元素粘接到myList2链表的第一个位置(pos及其后元素均后移)
myList2.splice(myList2.begin(), myList1);
cout << "粘接后,打印myList2的数据:" << endl;
print(myList2);
cout << "粘接后,打印myList1的数据:" << endl;
print(myList1); // 粘接方法2:splice(iterator pos, list& lst, iterator del)
// 将myList1链表元素从第二个开始粘接到myList3链表的第一个位置
myList1.assign(, );
myList3.assign(, );
cout << endl << "打印myList3的数据:" << endl;
print(myList3);
cout << "打印myList1的数据:" << endl;
print(myList1);
myList3.splice(myList3.begin(), myList1, ++myList1.begin());
cout << "粘接后,打印myList3的数据:" << endl;
print(myList3);
cout << "粘接后,打印myList1的数据:" << endl;
print(myList1); // 粘接方法3:splice(iterator pos, list& lst, iterator start, iterator end)
// 将myList1链表元素从第二个开始粘接到myList4链表的第二个位置
myList1.push_back();
myList1.push_back();
myList1.push_back();
myList1.push_back();
myList4.assign(, );
cout << endl << "打印myList4的数据:" << endl;
print(myList4);
cout << "打印myList1的数据:" << endl;
print(myList1);
myList4.splice(++myList4.begin(), myList1, ++myList1.begin(), myList1.end());
cout << "粘接后,打印myList4的数据:" << endl;
print(myList4);
cout << "粘接后,打印myList1的数据:" << endl;
print(myList1); system("pause");
} // run out:
/*
打印myList2的数据:
22
打印myList1的数据:
10 10 10 10 10
粘接后,打印myList2的数据:
10 10 10 10 10 22
粘接后,打印myList1的数据: 打印myList3的数据:
22 22
打印myList1的数据:
11 11
粘接后,打印myList3的数据:
11 22 22
粘接后,打印myList1的数据:
11 打印myList4的数据:
44 44 44 44
打印myList1的数据:
11 12 13 14 15
粘接后,打印myList4的数据:
44 12 13 14 15 44 44 44
粘接后,打印myList1的数据:
11
请按任意键继续. . .
*/

(7)swap方法。交换两个链表中的元素。

应用示例代码如下:

 #include <list>
#include <iostream>
using namespace std; // 打印链表数据信息
void print (const list<int> & tempList)
{
list<int>::const_iterator cIter = tempList.cbegin();
for (; cIter != tempList.cend(); ++cIter)
{
cout << (*cIter) << " ";
}
cout << endl;
} void main()
{
list<int> myList1, myList2;
for (int i = ; i < ; ++i)
{
myList1.push_back(rand() % );
}
for (int j = ; j < ; ++j)
{
myList2.push_back(rand() % );
}
cout << "打印myList1的数据:" << endl;
print(myList1);
cout << "打印myList2的数据:" << endl;
print(myList2);
myList1.swap(myList2);
cout << "交换后,打印myList1的数据:" << endl;
print(myList1);
cout << "交换后,打印myList2的数据:" << endl;
print(myList2); system("pause");
}
// run out:
/*
打印myList1的数据:
41 67 34 0 69 24 78 58 62 64
打印myList2的数据:
105 145 81 27 161 91 195 142 27 36
交换后,打印myList1的数据:
105 145 81 27 161 91 195 142 27 36
交换后,打印myList2的数据:
41 67 34 0 69 24 78 58 62 64
请按任意键继续. . .
*/

(8)待续。。。。

【3】list与vector区别总结

数组与链表的优缺点;

数组:

优点:访问效率高,内存为连续的区域。

缺点:添加、删除操作效率低。大小固定,不适合动态存储(不方便动态添加)。

链表:

优点:一般内存不连续。添加、删除效率高。大小可变。

缺点:只能通过指针顺序访问,查询效率低。

Good  Good  Study, Day  Day  Up.

顺序  选择  循环  总结

STL容器之list的更多相关文章

  1. [知识点]C++中STL容器之map

    UPDATE(20190416):写完vector和set之后,发现不少内容全部引导到map上了……于是进行了一定的描述补充与更正. 零.STL目录 1.容器之map 2.容器之vector 3.容器 ...

  2. [知识点]C++中STL容器之set

    零.STL目录 1.容器之map 2.容器之vector 3.容器之set 一.前言 继上期的vector之后,我们又迎来了另一个类数组的STL容器——set. 二.用途与特性 set,顾名思义,集合 ...

  3. [知识点]C++中STL容器之vector

    零.STL目录 1.容器之map 2.容器之vector 3.容器之set 一.前言 关于STL和STL容器的概念参见STL系列第一篇——map(见上).今天介绍第二个成员——vector. 二.用途 ...

  4. STL容器之map

    [1]map容器 map 是关联容器.容器中的每一个元素都是由一个键值和一个数据值组成的. set 是一个集合它以其元素作为键值(同一个键值只能出现一次),且默认以升序排列. list 是一个顺序容器 ...

  5. STL容器之vector

    [1]模板类vector 模板类vector可理解为广义数组.广义数组,即与类型无关的数组,具有与数组相同的所有操作. 那么,你或许要问:既然C++语言本身已提供了一个序列式容器array,为什么还要 ...

  6. C++ STL容器之 stack

    STL 中的 stack 是一种容器适配器,而不是一种容器. 它是容器适配器是指,只要支持一系列方法的容器(empty, size, back, push_back, pop_back),都能作为st ...

  7. STL容器之set

    [1]set容器 一个集合(set)是一个容器,它其中所包含的元素的值是唯一的. [2]set容器方法 (1)set构造函数.插入函数.遍历过程 应用示例代码如下: #include <set& ...

  8. STL容器之deque

    [1]deque容器 deque 是对 vector 和 list 优缺点的结合,它是处于两者之间的一种容器. [2]deque方法集 应用示例代码: #include <deque> # ...

  9. STL容器之Array[转]

    转自https://blog.csdn.net/sin_geek/article/details/51067874 作者 Sin_Geek 简介 array在头文件<array> 中定义 ...

随机推荐

  1. shell脚本中sqlite3命令查询数据库失败返回空,并将错误信息打印到标准错误输出

    shell脚本中sqlite3命令查询数据库失败返回空,并将错误信息打印到标准错误输出 如: #/bin/sh local ret='sqlite3 test.db "select test ...

  2. JavaScript、关于元素的offset~和client~

    1.偏移量(offset dimension)   =>offsetLeft(元素距离其父元素左边框(/上边框)的距离) =>offsetTop =>offsetWidth(元素的宽 ...

  3. 1-2-编译U-boot

    1-2-编译U-boot 1.su+enter进入超级用户模式. 2.cd /mnt/+两次Tab去到根目录,ls显示共享文件夹里的文件. 3.解压tar xvfj uboot_TQ210_1.3.4 ...

  4. vue package-lock.json的作用

    其实用一句话来概括很简单,就是锁定安装时的包的版本号,并且需要上传到git,以保证其他人在npm install时大家的依赖能保证一致.

  5. mysql sysbench基准测试

    git项目地址: https://github.com/akopytov/sysbench 利用sysbench很容易对mysql做性能基准测试(当然这个工具很强大,除了测试主流数据库性能,还能测试其 ...

  6. RN-系列

    8081端口被占用,McAfee Agent关不掉 sudo lsof -n -i4TCP:8081 sudo launchctl list | grep 5693 sudo launchctl re ...

  7. os.path.join路径拼接

    #import os print("0:", os.path.join('/aaa', 'bbb', 'ccc.txt')) #0: /aaa\bbb\ccc.txt 多数这种用法 ...

  8. SmartGit 过期破解 - 授权文件 Free Trial License to Non-Commercial

    亲测可用~ Windows: %APPDATA%/syntevo/SmartGit/OS X:    ~/Library/Preferences/SmartGit/Unix/Linux:  ~/.sm ...

  9. vue--postcss插件

     vue-loader里的postcss插件会帮你抹平浏览器兼容的写法

  10. podofo 一点小分享

    PDF 的开源库,大多是Java,或C#的,但C++也有一个很不错的PDF开源库:PoDoFo 我司的PDF签章产品中,我就是用这个PoDoFo库来做的底层 但是国外开源库对中文支持都是或多或少有点问 ...