STL之list
template < class T, class Alloc = allocator<T> > class list;
List
Lists are sequence containers that allow constant time insert and erase operations anywhere within the sequence, and iteration in both directions.
[list是顺序容器,在lis的任意位置进行插入和删除操作的时间复杂度是一个常数]
List containers are implemented as doubly-linked lists; Doubly linked lists can store each of the elements they contain in different and unrelated storage locations. The ordering is kept internally by the association to each element of a link to the element preceding it and a link to the element following it.
[list容器是通过双向链表实现的]
Compared to other base standard sequence containers (array, vector and deque), lists perform generally better in inserting, extracting and moving elements in any position within the container for which an iterator has already been obtained, and therefore also in algorithms that make intensive use of these, like sorting algorithms.
[相较于其他顺序容器(array, vector, deque),list在插入和删除方面的性能一般比较好,因此在算法中list很经常使用,比如排序算法]
The main drawback of lists to these other sequence containers is that they lack direct access to the elements by their position; For example, to access the sixth element in a list, one has to iterate from a known position (like the beginning or the end) to that position, which takes linear time in the distance between these. They also consume some extra memory to keep the linking information associated to each element (which may be an important factor for large lists of small-sized elements).
[相较于其他顺序容器,list的缺陷是在根据位置直接获取元素这一方面,举个例子,如果我们想要获取list中的第六个元素,则必须先将迭代器指向已知位置,然后再迭代到目标位置,该操作的时间复杂度是线性的。另外,list还需要额外的内存来保存元素之间相互关联的结点信息,这一点或许是大型链表或者长度较小的链表的重要影响因素]
/* size_type size()const; //返回list中元素的个数 bool empty()const; //判断list是否为空 void clear(); //清空list void swap(list& x); //交换两个list list& operator=(const list& x); reference front(); //返回list中第一个元素的引用 reference back(); //返回list中最后一个元素的引用 void push_back(const value_type& val); //在list尾部添加一个元素val void pop_back(); //删除list尾部的元素 void push_front(const value_type& val); //在list头部添加一个元素val void pop_front(); //删除list头部的元素 iterator begin(); //返回指向list中第一个元素的迭代器 iterator end(); //返回指向list中最后一个元素的下一位(past-the-end)的迭代器 reverse_iterator rbegin(); //返回指向list中最后一个元素的迭代器 reverse_iterator rend(); //返回指向list中第一个元素的前一位(preceding the first element)的迭代器 //assign void assign (size_type n, const value_type& val); void assign (InputIterator first, InputIterator last);
Assign new content to container
Assign new contents to the list container, replacing its current contents, and modifying its size accordingly.
[重新分配list的元素并相应改变list的长度]
Any elements held in the container before the call are destroyed and replaced by newly constructed elements(no assignments of elements take place)
[容器中原有元素均被销毁并替换为新元素] */ #include <iostream> #include <list> int main () { std::list<int> first; std::list<int> second; first.assign (7,100); // 7 ints with value 100 second.assign (first.begin(),first.end()); // a copy of first int myints[]={1776,7,4}; first.assign (myints,myints+3); // assigning from array std::cout << "Size of first: " << int (first.size()) << '\n'; std::cout << "Size of second: " << int (second.size()) << '\n'; system("pause"); return 0; }
/* //insert iterator insert (iterator position, const value_type& val); void insert (iterator position, size_type n, const value_type& val); void insert (iterator position, InputIterator first, InputIterator last); Insert elements The container is extended by inserting new elements before the element at the specified position. [在position指向的元素之前插入新元素] This effectively increases the list size by the amount of elements inserted. [该操作能够有效的list的长度] Unlike other standard sequence containers, list objects are specifically designed to be efficient inserting and removing elements in any position, even in the middle of the sequence. [不同于其他标准顺序容器,list是专门为在任意位置(即便是在中部)高效地插入和删除元素而设计的] Return value An iterator that points to the first of the newly inserted elements. [返回值是指向第一个新插入元素的迭代器] Member type iterator is a bidirectional iterator type that points to elements. [iterator是一个指向元素的双向迭代器] */ #include <iostream> #include <list> #include <vector> int main () { std::list<int> mylist; std::list<int>::iterator it; // set some initial values: for (int i=1; i<=5; ++i) mylist.push_back(i); // 1 2 3 4 5 it = mylist.begin(); ++it; // it points now to number 2 ^ mylist.insert (it,10); // 1 10 2 3 4 5 // "it" still points to number 2 ^ mylist.insert (it,2,20); // 1 10 20 20 2 3 4 5 --it; // it points now to the second 20 ^ std::vector<int> myvector (2,30); mylist.insert (it,myvector.begin(),myvector.end()); // 1 10 20 30 30 20 2 3 4 5 // ^ std::cout << "mylist contains:"; for (it=mylist.begin(); it!=mylist.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; system("pause"); return 0; }
/* iterator erase(iterator position); iterator erase(iterator first, iterator last); Erase elements Removes from the list container either a single element (position) or a range of elements ([first,last)). [从容器中删除一个元素(position处)或者一组元素(范围是[first, last])] This effectively reduces the container size by the number of elements removed, which are destroyed. [该操作会有效地缩小vector的长度] Unlike other standard sequence containers, list bjects are specifically designed to be efficient inserting and removing elements in any position, even in the middle of the sequence. [不同于其他标准顺序容器,list是专门为高效地在任意位置(即便是在中间位置)进行插入和删除操作而设计的] Return value An iterator pointing to the element that followed the last element erased by the function call. This is the container end if the operation erased the last element in the sequence. [返回值是最后一个被删除元素的的下一个元素的迭代器,如果删除操作发生在尾部,则返回的是end] */ #include <iostream> #include <list> int main() { std::list<int> mylist; std::list<int>::iterator it1,it2; // set some values: for (int i=1; i<10; ++i) mylist.push_back(i*10); // 10 20 30 40 50 60 70 80 90 it1 = it2 = mylist.begin(); // ^^ advance (it2,6); // ^ ^ ++it1; // ^ ^ it1 = mylist.erase (it1); // 10 30 40 50 60 70 80 90 // ^ ^ it2 = mylist.erase (it2); // 10 30 40 50 60 80 90 // ^ ^ ++it1; // ^ ^ --it2; // ^ ^ mylist.erase (it1,it2); // 10 30 60 80 90 // ^ std::cout << "mylist contains:"; for (it1=mylist.begin(); it1!=mylist.end(); ++it1) std::cout << ' ' << *it1; std::cout << '\n'; system("pause"); return 0; }
注: //std::advance void advance (InputIterator& it, Distance n)Advance iterator Advances the iterator it by n element positions. [将迭代器it往后移n个单位] If it is a random-access iterator, the function uses just once operator+ or operator-. Otherwise, the function uses repeatedly the increase or decrease operator (operator++ or operator--) until n elements have been advanced. [如果迭代器it是个随机存储迭代器,则该函数使用的是operator+或者operator-来移动n个单位;否则使用的是operator++或者operator--来移动n个单位]
/* void resize(size_type n, value_type val = value_type()); Change size Resizes the container so that it contains n elements. [改变容器的大小使之长度为n] If n is smaller than the current container size, the content is reduced to its first n elements, removing those beyond (and destroying them). [如果n小于当前容器长度,则只保留前n个元素,其余元素销毁] If n is greater than the current container size, the content is expanded by inserting at the end as many elements as needed to reach a size of n. If val is specified, the new elements are initialized as copies of val, otherwise, they are value-initialized. [如果n大于当前容器的长度,则用指定元素填充剩下的元素;若没有指定填充元素,则用默认值填充] */ #include <iostream> #include <list> int main () { std::list<int> mylist; // set some initial content: for (int i=1; i<10; ++i) mylist.push_back(i); mylist.resize(5); mylist.resize(8,100); mylist.resize(12); std::cout << "mylist contains:"; for (std::list<int>::iterator it=mylist.begin(); it!=mylist.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; system("pause"); return 0; }
/* void reverse(); Reverse the order of elements Reverses the order of the elements in the list container. [反转list容器中的元素] */ #include <iostream> #include <list> int main() { std::list<int> mylist; for(int i=1; i<10; i++) mylist.push_back(i); mylist.reverse(); std::cout<<"mylist contains:"; for(std::list<int>::iterator it = mylist.begin(); it != mylist.end(); ++it) std::cout<<' '<<*it; std::cout<<'\n'; system("pause"); return 0; }
/* //remove void remove(const value_type& val); Remove elements with specific value Removes from the container all the elements that compare equal to val. This calls the destructor of these objects and reduces the container size by the number of elements removed. [删除容器中所有与val相等的元素,该操作会调用这些对象的析构函数并相应的减小容器的长度] Unlike member function list::erase, which erases elements by their position (using an iterator), this function (list::remove) removes elements by their value. [不同于list::erase的通过位置利用迭代器来删除元素,list::remove是通过元素值来删除元素] A similar function, list::remove_if, exists, which allows for a condition other than an equality comparison to determine whether an element is removed. [与remove()函数相似的remove_if()函数允许根据一个条件来判断元素是否被删除] */ #include <iostream> #include <list> int main () { int myints[]= {17,89,7,14, 89, 17}; std::list<int> mylist (myints,myints+6); mylist.remove(89); std::cout << "mylist contains:"; for (std::list<int>::iterator it=mylist.begin(); it!=mylist.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; system("pause"); return 0; }
/* template<class Predicate> void remove_if(Predicate pred); Remove elements fulfilling condition Removes from the container all the elements for which Predicate pred returns true. This calls the destructor of these objects and reduces the container size by the number of elements removed. [对于容器中的元素,如果Predicate pred返回真则删除。该操作会调用对象的析构函数并相应地减小容器的长度] The function calls pred(*i) for each element (where i is an iterator to that element). Any of the elements in the list for which this returns true, are removed from the container. [对于容器中的每个元素,该函数会调用pred(*i),其中i是指向元素的迭代器,如果pred(*i)返回真则删除该元素]
pred
This can either be a function pointer or a function object.
*/ #include <iostream> #include <list> //a predict implemented as a function bool single_digit(const int& value) {return (value<10);} //a predict implemented as a class struct is_odd{ bool operator() (const int& value) {return (value%2)==1;} }; int main() { int myints[] = {15, 36, 7, 17, 20, 39, 4, 1}; std::list<int> mylist(myints, myints+8); // 15 36 7 17 20 39 4 1 mylist.remove_if(single_digit); // 15 36 17 20 39 mylist.remove_if(is_odd()); // 36 20 std::cout<<"mylist contains:"; for(std::list<int>::iterator it = mylist.begin(); it != mylist.end(); ++it) std::cout<<' '<<*it; std::cout<<'\n'; system("pause"); return 0; }
/* void sort(); template<class Compare> void sort(Compare comp); Sort elements in container Sorts the elements in the list, altering their position within the container. [将list中的元素进行排序] The sorting is performed by applying an algorithm that uses either operator< (in version (1)) or comp (in version (2)) to compare elements. This comparison shall produce a strict weak ordering of the elements (i.e., a consistent transitive comparison, without considering its reflexiveness). [排序是通过operator<(方式一)或者comp(方式二)来实现的,且应该是对元素进行严格弱排序] The resulting order of equivalent elements is stable: i.e., equivalent elements preserve the relative order they had before the call. [相等元素排序位置保持不变] The entire operation does not involve the construction, destruction or copy of any element object. Elements are moved within the container. [排序过程不会涉及到元素的构造、析构或者赋值,排序过程中,元素都是在容器内移动到相应位置]
comp
This shall be a function pointer or a function object.
[comp应该是一个函数指针或者函数对象] */ #include <iostream> #include <list> #include <string> #include <cctype> // a comparison implemented as a function bool compare_nocase (const std::string& first, const std::string& second) { unsigned int i = 0; while((i<first.length() && i<second.length())) { if(tolower(first[i]) < tolower(second[i])) return true; else if(tolower(first[i]) > tolower(second[i])) return false; i++; } return (first.length() < second.length()); } // a comparison implemented as a class struct compNoCase{ bool operator() (const std::string& first, const std::string& second) { unsigned int i = 0; while((i<first.length() && i<second.length())) { if(tolower(first[i]) < tolower(second[i])) return true; else if(tolower(first[i]) > tolower(second[i])) return false; i++; } return (first.length() < second.length()); } }; int main() { std::list<std::string> mylist; std::list<std::string>::iterator it; mylist.push_back("one"); mylist.push_back("two"); mylist.push_back("Three"); mylist.sort(); std::cout << "mylist contains:"; for (it=mylist.begin(); it!=mylist.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; mylist.sort(compare_nocase); std::cout << "mylist contains:"; for (it=mylist.begin(); it!=mylist.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; std::list<std::string> mylist1; std::list<std::string>::iterator it1; mylist1.push_back("Tom"); mylist1.push_back("Jack"); mylist1.push_back("tina"); mylist1.push_back("mary"); mylist1.sort(compNoCase()); std::cout << "mylist1 contains:"; for (it1=mylist1.begin(); it1!=mylist1.end(); ++it1) std::cout << ' ' << *it1; std::cout << '\n'; system("pause"); return 0; }
/* void unique(); template <class BinaryPredicate> void unique (BinaryPredicate binary_pred); Remove duplicate values The version with no parameters (1), removes all but the first element from every consecutive group of equal elements in the container. [第一种方式会删除所有与前一个元素相等的元素] Notice that an element is only removed from the list container if it compares equal to the element immediately preceding it. Thus, this function is especially useful for sorted lists. [需要注意的是,该函数只会删除与前一个元素相等的元素,因此该函数特别适用于经过排序的列表] The second version (2), takes as argument a specific comparison function that determine the "uniqueness" of an element. In fact, any behavior can be implemented (and not only an equality comparison), but notice that the function will call binary_pred(*i,*(i-1)) for all pairs of elements (where i is an iterator to an element, starting from the second) and remove i from the list if the predicate returns true. [第二种形式会通过比较函数(即unique的参数)来判断元素是否唯一。实际上,这种形式可以实现多种行为(不仅仅是比较两个元素是否相等),但需要注意的是,对于容器中的所有元素对,该函数都会调用binary_pred(*i, *(i-1)),并删除使得函数返回真的元素*i。(其中i是指向元素的迭代器,从第二个元素开始)] The elements removed are destroyed. [被删除的元素都被销毁]
binary_pred
This shall be a function pointer or a funtion object.
[binary_pred应该是一个函数指针或者函数对象]
*/ #include <iostream> #include <cmath> #include <list> // a binary predicate implemented as a function bool same_integral_part (double first, double second) { return (int(first) == int(second)); } // a binary predicate implemented as a class struct is_near{ bool operator() (double first, double second) { return (fabs(first-second)<5.0); } }; int main() { double mydoubles[]={ 12.15, 2.72, 73.0, 12.77, 3.14, 12.77, 73.35, 72.25, 15.3, 72.25 }; std::list<double> mylist (mydoubles,mydoubles+10); mylist.sort(); // 2.72, 3.14, 12.15, 12.77, 12.77, // 15.3, 72.25, 72.25, 73.0, 73.35 mylist.unique(); // 2.72, 3.14, 12.15, 12.77 // 15.3, 72.25, 73.0, 73.35 mylist.unique (same_integral_part); // 2.72, 3.14, 12.15 // 15.3, 72.25, 73.0 mylist.unique (is_near()); // 2.72, 12.15, 72.25 std::cout << "mylist contains:"; for (std::list<double>::iterator it=mylist.begin(); it!=mylist.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; system("pause"); return 0; }
注: int abs(int x); //返回x的绝对值 double fabs(double x); //返回x的绝对值 double floor(double x); //向下取整 double ceil(double x); //向上取整
/* void splice (iterator position, list& x); void splice (iterator position, list& x, iterator i); void splice (iterator position, list& x, iterator first, iterator last); Transfer elements from list to list Transfers elements from x into the container, inserting them at position. [将元素从容器x插入到当前容器的position处] This effectively inserts those elements into the container and removes them from x, altering the sizes of both containers. The operation does not involve the construction or destruction of any element. They are transferred, no matter whether x is an lvalue or an rvalue, or whether the value_type supports move-construction or not. [该操作能够高效的将元素从容器x删除并插入到当前容器中并相应改变两个容器的长度,该操作对元素进行的是转移,而不会对任何元素进行构造与析构] The first version (1) transfers all the elements of x into the container. [第一种形式会将容器x中的所有元素都转移到当前容器中] The second version (2) transfers only the element pointed by i from x into the container. [第二种形式只会将容器x中迭代器i所指向的元素转移到当前容器中] The third version (3) transfers the range [first,last) from x into the container. [第三种形式会将容器x中[first, last)范围内的元素转移到当前容器中] */ #include <iostream> #include <list> int main () { std::list<int> mylist1, mylist2; std::list<int>::iterator it; // set some initial values: for (int i=1; i<=4; ++i) mylist1.push_back(i); // mylist1: 1 2 3 4 for (int i=1; i<=3; ++i) mylist2.push_back(i*10); // mylist2: 10 20 30 it = mylist1.begin(); ++it; // points to 2 mylist1.splice (it, mylist2); // mylist1: 1 10 20 30 2 3 4 // mylist2 (empty) // "it" still points to 2 (the 5th element) mylist2.splice (mylist2.begin(),mylist1, it); // mylist1: 1 10 20 30 3 4 // mylist2: 2 // "it" is now invalid. it = mylist1.begin(); std::advance(it,3); // "it" points now to 30 mylist1.splice ( mylist1.begin(), mylist1, it, mylist1.end()); // mylist1: 30 3 4 1 10 20 std::cout << "mylist1 contains:"; for (it=mylist1.begin(); it!=mylist1.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; std::cout << "mylist2 contains:"; for (it=mylist2.begin(); it!=mylist2.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; system("pause"); return 0; }
/* //merge void merge(list& x); template<class Compare> void merge(list& x, Compare comp); Merge sorted lists Merges x into the list by transferring all of its elements at their respective ordered positions into the container (both containers shall already be ordered). [将容器x中的元素转移到当前容器中并放置在各自经过排序的位置上(容器x和当前容器首先必须是排序过的)] This effectively removes all the elements in x (which becomes empty), and inserts them into their ordered position within container (which expands in size by the number of elements transferred). The operation is performed without constructing nor destroying any element: they are transferred, no matter whether x is an lvalue or an rvalue, or whether the value_type supports move-construction or not. [该函数能够高效的将x中的所有元素插入到当前容器中各自的排序位置上,操作完成后,容器x变为空,当前容器相应增长。该操作中的元素都是转移,而不会涉及到构造和析构任何元素,] The template versions with two parameters (2), have the same behavior, but take a specific predicate (comp) to perform the comparison operation between elements. This comparison shall produce a strict weak ordering of the elements (i.e., a consistent transitive comparison, without considering its reflexiveness). [第二种带两个参数的形式中的comp需要提供元素间的比较操作,且该比较操作是一个严格弱排序] This function requires that the list containers have their elements already ordered by value (or by comp) before the call. For an alternative on unordered lists, see list::splice. [该函数要求容器事先是排好序的,对于其他情况请参见list::splice] The resulting order of equivalent elements is stable (i.e., equivalent elements preserve the relative order they had before the call, and existing elements precede those equivalent inserted from x). [如果两个元素是相等的,则它们的排序是固定的] The function does nothing if (&x == this). [如果&x==this,该函数不会起任何作用]
comp
This shall be a function pointer or a function object.
*/ #include <iostream> #include <list> // a comparision implemented as a function bool mycomparison (double first, double second) { return ( int(first)<int(second) ); } // a comparision implemented as a class struct myComp{ bool operator() (double first, double second) { return (int(first) < int(second)); } }; int main () { std::list<double> first, second; first.push_back (3.1); first.push_back (2.2); first.push_back (2.9); second.push_back (3.7); second.push_back (7.1); second.push_back (1.4); first.sort(); //2.2 2.9 3.1 second.sort(); //1.4 3.7 7.1 first.merge(second); // first: 1.4 2.2 2.9 3.1 3.7 7.1 // second: empty second.push_back (2.1); first.merge(second,mycomparison); //first: 1.4 2.2 2.9 2.1 3.1 3.7 7.1 //second: empty second.push_back (4.6); first.merge(second,myComp()); //first: 1.4 2.2 2.9 2.1 3.1 3.7 4.6 7.1 //second: empty std::cout << "first contains:"; for (std::list<double>::iterator it=first.begin(); it!=first.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; system("pause"); return 0; }