原理
list是一个双向链表,以结点为单位存放数据,结点的地址在内存中不一定连续,每次插入或删除一个元素,就配置或释放一个元素空间。它有一个重要性质:插入操作和删除操作都不会造成原有的list迭代器失效,每次插入或删除一个元素就配置或释放一个元素空间。也就是说,对于任何位置的元素插入或删除,list永远是常数时间。(优点:删除插入删除)
list排序函数的排序原理
将前两个元素合并,再将后两个元素合并,然后合并这两个子序列成4个元素的子序列,重复这一过程,得到8个,16个,...,子序列,最后得到的就是排序后的序列。
时间复杂度:O(nlgn)
list的功能方法
实际上有两种List:
ArrayList:其优点在于随机访问元素,向list中间插入删除 的开销大。
LinkedList,随机访问很慢, 适合顺序访问,向中间插入删除效率高。
List : 次序是List最重要的特点:它保证维护元素特定的顺序。List为Collection添加了许多方法,使得能够向List中间插入与移除元素(这只推荐LinkedList使用)一个List可以生成ListIterator,使用它可以从两个方向遍历List,也可以从List中间插入和移除元素。
ArrayList : 由数组实现的List。允许对元素进行快速随机访问,但是向List中间插入与移除元素的速度很慢。ListIterator只应该用来由后向前遍历ArrayList,而不是用来插入和移除元素。因为那比LinkedList开销要大很多。
LinkedList : 对顺序访问进行了优化,向List中间插入与删除的开销并不大。随机访问则相对较慢。(使用ArrayList代替)还具有下列方法:addFirst(), addLast(), getFirst(),getLast(), removeFirst() 和 removeLast(), 这些方法 (没有在任何接口或基类中定义过)使得LinkedList可以当作堆栈、队列和双向队列使用。
list与vector的区别
list和vector的区别,本质区别:list是链式存储,vector在内存中是连续区别的,有本质区别而导致下面区别
1)list不支持随机访问,vector可以像数组那样使用平[ ] 访问元素,而list是不可以的。
2)list的插入和删除效率很高,所以list有push_front、pop_front、sort而vector中这些操作的效率太低了。
3)list的一些特有的函数remove、reverse、unique、splice、merge功能(这些连deque中都没有的)
//链表的删除操作除了erase之外,还有一个romove。
//remove与erase不同,erase是删除指定位置的节点,
而remove是删除指定值的节点
33 cout<<"删除第一个元素:"<<endl;
34 link.erase(link.begin());
35
36 cout<<"删除值为6的所有元素"<<endl;
37 link.remove(6);
38
40 //排序,list中的排序有直接的函数而不需要使用algorithm里面的函数
44 link.sort();
46
47 //反转reverse
51 link.reverse();
52
54 //unique功能去除链表中相邻的重复元素
55 int a[10]={1,1,3,2,2,2,1,1,2,3};
56 list<int> link(&a[0],&a[9]+1);
59 link.unique();
62
63 //在指定list的迭代器位置上拼接另一个链表中另一个迭代器或者另一个迭代器指定的区间的数据
64 //splice
65 int a1[3]={1,3,5};
66 int a2[3]={2,4,6};
67 list<int>link1(&a1[0],&a1[2]+1);
68 list<int>link2(&a2[0],&a2[2]+1);
74 link1.splice(link1.begin(),link2,link2.begin()); link1.splice(link1.end(),link2,link2.begin(),link2.end());
87
93 //融合两个排序的list,融合的list依然是排序的
94 int b1[3]={2,4,6};
95 int b2[3]={1,3,5};
96 list<int>l1(&b1[0],&b1[2]+1);
97 list<int>l2(&b2[0],&b2[2]+1);
103 l1.merge(l2);
111
============================== 附录 ===========
1、vector、list、map、deque用erase(it)后,迭代器的变化。
vector和deque是序列式容器,其内存分别是连续空间和分段连续空间,删除迭代器it后,其后面的迭代器都失效了,此时it及其后面的 迭代器会自动加1,使it指向被删除元素的下一个元素。
list删除迭代器it时,其后面的迭代器都不会失效,将前面和后面连接起来即可。
map也是只能使当前删除的迭代器失效,其后面的迭代器依然有效。
2、 特别注意 的地方:
(1)STL中迭代器容器中都要注意的地方(vector中已经提到):
1)任何时候同时使用两个迭代器产生的将会是一个前闭后开的区间(具体见插入和删除的例子)
2)begin()指向的是vec中的第0个元素,而end是指向最后一个元素的后面一个位置(不是最后一个元素)
3)迭代器的时效性,如果一个迭代器所指向的内容已经被删除,而后又使用该迭代器的话,会造成意想不到的后果。
(2)list的迭代器是双向迭代器(只能++ --,没有偏移功能)而不是像vector那样的随机迭代器(和指针几乎一样的所有功能)