2012年10月27日整理 郑海波 http://blog.csdn.net/nuptboyzhb/article/details/8120397
所有涉及到的程序下载:http://download.csdn.net/detail/nuptboyzhb/4730951
(一)list简介:
list不像vector那样,list的内存分配时非连续的,因此,只能通过迭代器来访问list中的元素。另外,list在头和尾都可以插入元素
vector的整理参见:http://blog.csdn.net/nuptboyzhb/article/details/7482923
(二)创建一个list1.首先包含list的头文件2.使用标准的std命名空间#include <list>usingnamespacestd;一下是构造list的不同方法:[c++ code list1.cpp]
- <span style="font-size:18px;">#pragma warning(disable:4786)
- #include <iostream>
- #include <list>
- #include <string>
- using namespace std;
- class Student{
- private:
- int ID;
- string Name;
- public:
- Student(int ID,string Name)
- {
- this->ID=ID;
- this->Name=Name;
- }
- int getID()
- {
- return ID;
- }
- string getName()
- {
- return Name;
- }
- };
- int main()
- {
- // create an empty list (of zero size) capable of holding doubles
- list<double> list0;
- cout << "Size of list0 is " << list0.size() << endl;
- // create a list with 5 empty elements
- list<double> list1(5);
- cout << "Size of list1 is " << list1.size() << endl;
- // create a list with 5 elements, each element having the value 10.2
- list<double> list2(5, 10.2);
- cout << "list2: ";
- list<double>::iterator it;
- for(it = list2.begin(); it != list2.end(); ++it)
- cout << *it << " ";
- cout << endl;
- // create a list based on an array of elements
- // only the first 5 elements of the array are copied into the vector
- double array[8] = {3.45, 67, 10, 0.67, 8.99, 9.78, 6.77, 34.677};
- list<double> list3(array, array + 5);
- cout << "list3: ";
- for(it = list3.begin(); it != list3.end(); ++it)
- cout << *it << " ";
- cout << endl;
- // use the copy constructor to copy list3 list into list3copy list
- list<double> list3copy(list3);
- cout << "list3copy: ";
- for(it = list3copy.begin(); it != list3copy.end(); ++it)
- cout << *it << " ";
- cout << endl;
- // assign 5 values of 10.2 to the list
- list<double> list4;
- list4.assign(5, 10.2);
- cout << "list4: ";
- for(it = list4.begin(); it != list4.end(); ++it)
- cout << *it << " ";
- cout << endl;
- //定义自己的数据类型
- list<Student> list5;
- Student stu1(1,"ZhengHaibo");
- Student stu2(2,"nupt");
- list5.push_back(stu1);
- list5.push_back(stu2);
- list<Student>::iterator iter_stu;
- cout << "list5: "<<endl;
- for (iter_stu=list5.begin();iter_stu!=list5.end();iter_stu++)
- {
- cout<<"ID:"<<iter_stu->getID()<<" Name:"<<iter_stu->getName()<<endl;
- }
- return 0;
- // Output
- // Size of list0 is 0
- // Size of list1 is 5
- // list2: 10.2 10.2 10.2 10.2 10.2
- // list3: 3.45 67 10 0.67 8.99
- // list3copy: 3.45 67 10 0.67 8.99
- // list4: 10.2 10.2 10.2 10.2 10.2
- //list5:
- //ID:1 Name:ZhengHaibo
- //ID:2 Name:nupt
- }
- </span>
(三)访问输出list中的值
在list中,由于其内存是非连续的,因此不能像vector那样,用[]操作符取值,只能用迭代器。
[c++ code list2.cpp]
- <span style="font-size:18px;">#pragma warning(disable:4786)
- #include <iostream>
- #include <list>
- #include <string>
- using namespace std;
- //Printing the elements of a list can only be done through iterators.
- void print(list<double> lst, char * name)
- {
- list<double>::iterator it;
- cout << name << ": ";
- for(it = lst.begin(); it != lst.end(); ++it)
- cout << *it << " ";
- cout << endl;
- }
- int main()
- {
- double array[8] = {3.45, 67, 10, 0.67, 8.99, 9.78, 6.77, 34.677};
- list<double> lst(array, array + 5);
- print(lst, "lst");
- cout << "lst in reverse order: ";
- list<double>::reverse_iterator rit;//
- for(rit = lst.rbegin(); rit != lst.rend(); ++rit)
- cout << *rit << " ";
- return 0;
- //Output
- // lst: 3.45 67 10 0.67 8.99
- // lst in reverse order: 8.99 0.67 10 67 3.45
- }</span>
(四)向list中插入元素
与vector相比,list除了有push_back()//在尾部插入 和 insert()之外,还有push_front()//即在链表的头部插入
[c++ code list3.cpp]
- <span style="font-size:18px;">#pragma warning(disable:4786)
- #include <iostream>
- #include <list>
- #include <string>
- using namespace std;
- //Printing the elements of a list can only be done through iterators.
- void print(list<double> lst, char * name)
- {
- list<double>::iterator it;
- cout << name << ": ";
- for(it = lst.begin(); it != lst.end(); ++it)
- cout << *it << " ";
- cout << endl;
- }
- int main()
- {
- list<double> lst;
- list<double>::iterator it;
- // add elements to the end of the list
- lst.push_back(2.4);
- lst.push_back(4.5);
- lst.push_back(0.98);
- print(lst, "lst");
- // insert value 6.7 in the second position in the list
- it = lst.begin();
- lst.insert(++it, 6.7);
- print(lst, "lst");
- // insert elements from the array at the end of the list
- double array[2] = {100.89, 789.76};
- it = lst.end();
- lst.insert(it, array, array + 2);
- print(lst, "lst");
- // add elements to the beginning of the list
- lst.push_front(0.45);
- lst.push_front(0.56);
- lst.push_front(0.78);
- print(lst, "lst");
- return 0;
- // Output
- // lst: 2.4 4.5 0.98
- // lst: 2.4 6.7 4.5 0.98
- // lst: 2.4 6.7 4.5 0.98 100.89 789.76
- // lst: 0.78 0.56 0.45 2.4 6.7 4.5 0.98 100.89 789.76
- }</span>
(五)删除list中的元素
主要有如下函数:pop_back(),pop_front(),erase(),remove(),remove_if(),unique(),clear()<empty()>;
与插入元素相对应,list用pop_back()//在尾部删除一个元素,pop_front()//在头部删除一个元素,erase()删除任意部位
[c++ code list4.cpp]
- <span style="font-size:18px;">#pragma warning(disable:4786)
- #include <iostream>
- #include <list>
- #include <string>
- using namespace std;
- //Printing the elements of a list can only be done through iterators.
- void print(list<double> lst, char * name)
- {
- list<double>::iterator it;
- cout << name << ": ";
- for(it = lst.begin(); it != lst.end(); ++it)
- cout << *it << " ";
- cout << endl;
- }
- int main()
- {
- double array[10] = {3.45, 67, 10, 0.67, 8.99, 9.78, 6.77, 34.677, 100.67, 0.99};
- list<double> lst(array, array + 10);
- list<double>::iterator it;
- print(lst, "lst");
- // remove the last element of the list
- lst.pop_back();
- print(lst, "lst");
- // remove the second element of the list
- it = lst.begin();
- lst.erase(++it);
- print(lst, "lst");
- // remove the first element of the list
- lst.pop_front();
- print(lst, "lst");
- return 0;
- // Output
- // lst: 3.45 67 10 0.67 8.99 9.78 6.77 34.677 100.67 0.99
- // lst: 3.45 67 10 0.67 8.99 9.78 6.77 34.677 100.67
- // lst: 3.45 10 0.67 8.99 9.78 6.77 34.677 100.67
- // lst: 10 0.67 8.99 9.78 6.77 34.677 100.67
- }</span>
另外,list还有remove()函数,remove()函数也是删除一个元素,但是,它的参数是元素的值或者是对象,而不是迭代器.同时,还有remove_if()函数,该函数的参数是一个函数,是一个返回值为bool,参数为元素类型的一个函数。
[c++ code list5.cpp]//注意:该程序在VC6.0下编译报错,建议使用g++或gcc。
- <span style="font-size:18px;">#pragma warning(disable:4786)
- #include <iostream>
- #include <list>
- #include <string>
- using namespace std;
- //Printing the elements of a list can only be done through iterators.</span>
- <span style="font-size:18px;"><a href="http://blog.csdn.net/nuptboyzhb/article/details/8120397" style="font-size: 18px; ">http://blog.csdn.net/nuptboyzhb/article/details/8120397</a></span>
- <span style="font-size:18px;">
- void print(list<double> lst, char * name)
- {
- list<double>::iterator it;
- cout << name << ": ";
- for(it = lst.begin(); it != lst.end(); ++it)
- cout << *it << " ";
- cout << endl;
- }
- bool zhb_predicate(double& element)
- {
- return (element >= 15.0) ? true : false;
- }
- int main()
- {
- double array[10] = {3.45, 67, 19.25, 0.67, 8.99, 9.78, 19.25, 34.677, 100.67, 19.25};
- list<double> lst(array, array + 10);
- print(lst, "lst");
- // remove all elements with value 19.25 from the list
- lst.remove(19.25);
- print(lst, "lst");
- lst.remove_if(zhb_predicate);
- print(lst, "lst");
- return 0;
- //lst: 3.45 67 19.25 0.67 8.99 9.78 19.25 34.677 100.67 19.25
- //lst: 3.45 67 0.67 8.99 9.78 34.677 100.67
- //lst: 3.45 0.67 8.99 9.78
- }</span>
另外一个删除元素的函数式unique()函数,还函数有2中调用方式。无参数调用的情况下,如果该元素与其前一个元素相同,则删除之。当然,我们也可以传递一个判断是否相等的一个函数。
[c++ code list6.cpp]//注意:该程序在VC6.0下编译报错,建议使用g++或gcc
- <span style="font-size:18px;">#pragma warning(disable:4786)
- #include <iostream>
- #include <list>
- #include <cmath>
- #include <string>
- using namespace std;
- //Printing the elements of a list can only be done through iterators.
- void print(list<double> lst, char * name)
- {
- list<double>::iterator it;
- cout << name << ": ";
- for(it = lst.begin(); it != lst.end(); ++it)
- cout << *it << " ";
- cout << endl;
- }
- bool almost_equal(double& el1, double& el2)
- {
- return (fabs(el1 - el2) <= 0.1) ? true : false;
- }
- int main()
- {
- double array[10] = {3.45, 0.67, 0.67, 0.62, 8.99, 8.98, 8.99, 34.677, 100.67, 19.25};
- list<double> lst(array, array + 10);
- print(lst, "lst");
- // remove all duplicate elements from the list
- lst.unique();
- print(lst, "lst");
- // remove all duplicate elements from the list
- lst.unique(almost_equal);
- print(lst, "lst");
- return 0;
- //Output
- // lst: 3.45 0.67 0.67 0.62 8.99 8.98 8.99 34.677 100.67 19.25
- // lst: 3.45 0.67 0.62 8.99 8.98 8.99 34.677 100.67 19.25
- // lst: 3.45 0.67 8.99 34.677 100.67 19.25
- }</span>
(六)链表的长度及重置链表的长度
与vector不同的是,list没有capacity() 和 reserve()函数。list用size获得链表的长度,用resize改变其大小。
[c++ code list7.cpp]
- <span style="font-size:18px;">#pragma warning(disable:4786)
- #include <iostream>
- #include <list>
- #include <cmath>
- #include <string>
- using namespace std;
- //Printing the elements of a list can only be done through iterators.
- void print(list<double> lst, char * name)
- {
- list<double>::iterator it;
- cout << name << ": ";
- for(it = lst.begin(); it != lst.end(); ++it)
- cout << *it << " ";
- cout << endl;
- }
- int main()
- {
- list<double> lst;
- lst.push_back(0.67);
- lst.push_back(7.89);
- lst.push_back(3.56);
- lst.push_back(10.67);
- lst.push_back(9.89);
- cout << "lst size is " << lst.size() << endl;
- print(lst, "lst");
- // case when new size <= size of list
- lst.resize(3);
- cout << "lst size is " << lst.size() << endl;
- print(lst, "lst");
- // case when new size > size of list
- lst.resize(10);
- cout << "lst size is " << lst.size() << endl;
- print(lst, "lst");
- return 0;
- // Output
- // lst size is 5
- // lst: 0.67 7.89 3.56 10.67 9.89
- // lst size is 3
- // lst: 0.67 7.89 3.56
- // lst size is 10
- // lst: 0.67 7.89 3.56 0 0 0 0 0 0 0
- }</span>
(七)反转一个链表
调用reverse()函数即可,很简单,不再举例。
(八)链表元素的排序
用sort()函数进行排序,默认情况下是从小到大,当然,也可以人为地改变。
[c++ code list8.cpp]//注意:该程序在VC6.0下编译报错,建议使用g++或gcc
- <span style="font-size:18px;">#pragma warning(disable:4786)
- #include <iostream>
- #include <list>
- #include <cmath>
- #include <string>
- using namespace std;
- //Printing the elements of a list can only be done through iterators.
- void print(list<double> lst, char * name)
- {
- list<double>::iterator it;
- cout << name << ": ";
- for(it = lst.begin(); it != lst.end(); ++it)
- cout << *it << " ";
- cout << endl;
- }
- int main()
- {
- double array[10] = {3.45, 3.455, 67, 0.67, 8.99, 9.0, 9.01, 34.677, 100.67, 19.25};
- list<double> lst(array, array + 10);
- print(lst, "lst");
- // sort the list;
- // < operator will be used as default
- // the elements will be sorted in ascending order
- lst.sort();
- print(lst, "lst in ascending order");
- // sort the list; specify the sorting function
- // > operator will be used in this case
- // the elements will be sorted in descending order
- lst.sort( greater<double>() );
- print(lst, "lst in descending order");
- // sort the list; specify the sorting function
- // < operator will be used in this case
- // the elements will be sorted in descending order
- lst.sort( less<double>() );
- print(lst, "lst in ascending order");
- return 0;
- // Output
- // lst: 3.45 3.455 67 0.67 8.99 9 9.01 34.677 100.67 19.25
- // lst in ascending order: 0.67 3.45 3.455 8.99 9 9.01 19.25 34.677 67 100.67
- // lst in descending order: 100.67 67 34.677 19.25 9.01 9 8.99 3.455 3.45 0.67
- // lst in ascending order: 0.67 3.45 3.455 8.99 9 9.01 19.25 34.677 67 100.67
- }</span>
(九)交换两个链表
直接调用swap()函数即可。
lst1.swap(lst2);
(十)合并两个链表
主要有两个函数:splice()和merge()
splice()有三种调用形式:
第一种: list1.splice(it1, list2).将list2中的所有元素拷贝到list1中。在list1中的起始位置是it1.复制结束后,list2将为空。
[c++ code]
- list<double> list1;
- list<double> list2;
- list1.push_back(1.0);
- list1.push_back(5.0);
- list1.push_back(6.0);
- list1.push_back(7.0);
- list1.push_back(8.0);
- list2.push_back(2.0);
- list2.push_back(3.0);
- list2.push_back(4.0);
- cout << "Before splice: " << endl;
- print(list1, "list1");
- print(list2, "list2");
- list<double>::iterator it1 = list1.begin();
- ++it1;
- // move all the elements of list2 into list1,
- // starting from the second position
- list1.splice(it1, list2);
- cout << "After splice: " << endl;
- print(list1, "list1");
- print(list2, "list2");
- // Output
- // Before splice:
- // list1: 1 5 6 7 8
- // list2: 2 3 4
- // After splice:
- // list1: 1 2 3 4 5 6 7 8
- // list2:
第二种调用形式:
list1.splice(it1, list2, it2)
这个功能是将list2中的元素,从it2开始,剪切到list1的it1起始的地方。
第三种调用形式:
list1.splice(it1, list2, it2begin, it2end)
merge函数的使用:
形式:list1.merge(list2)
注意:在使用merge之前,必须使list1和list2已经排好顺序。并且,合并之后list1仍然是有序的。
list<double> list1;
list<double> list2;
list1.push_back(1.0);
list1.push_back(5.0);
list1.push_back(6.0);
list1.push_back(7.0);
list1.push_back(8.0);
list2.push_back(2.0);
list2.push_back(3.0);
list2.push_back(4.0);
cout << "Beforemerge: " <<endl;
print(list1, "list1");
print(list2, "list2");
// merge the two lists
list1.merge(list2);
cout << "Aftermerge: " <<endl;
print(list1, "list1");
print(list2, "list2");
// Output
// Before merge:
// list1: 1 5 6 7 8
// list2: 2 3 4
// After merge:
// list1: 1 2 3 4 5 6 7 8
// list2:
(十一)二维链表
所谓二维链表就是链表的链表。
list< list<double> > matrix;
list<double> lst1(5, 6.713);
list<double> lst2(6, 5.678);
matrix.push_back(lst1);
matrix.push_back(lst2);
list< list<double> >::iterator it2d;
for(it2d = matrix.begin(); it2d != matrix.end(); it2d++)
print(*it2d, "row");
// Output
// row: 6.713 6.713 6.713 6.713 6.713
// row: 5.678 5.678 5.678 5.678 5.678 5.678
(十二)用户自定义的元素类型
为了能够使用stl中的算法,用户自定义的类必须实现很多运算符的重载。g++编译通过
- #pragma warning(disable:4786)
- #include <iostream>
- #include <list>
- #include <cmath>
- #include <string.h>
- using namespace std;
- class Person
- {
- char * name;
- char sex;
- int age;
- public:
- // constructor
- Person()
- {
- name = new char[strlen("Anonymous") + 1];
- sex = 'N';
- age = 0;
- }
- // constructor
- Person(char * pName, char pSex, int pAge)
- : sex(pSex), age(pAge)
- {
- name = new char[strlen(pName) + 1];
- strcpy(name, pName);
- }
- // copy constructor
- Person(const Person& rhs)
- : sex(rhs.sex), age(rhs.age)
- {
- name = new char[strlen(rhs.name) + 1];
- strcpy(name, rhs.name);
- }
- // overload the assignment operator
- Person& operator=(const Person& rhs)
- {
- name = new char[strlen(rhs.name) + 1];
- strcpy(name, rhs.name);
- sex = rhs.sex;
- age = rhs.age;
- return *this;
- }
- // overload the == operator
- // for sorting purposes, we consider that two Person objects are "equal"
- // if they have the same age
- bool operator==(const Person& rhs) const
- {
- return (age == rhs.age) ? true : false;
- }
- // overload the < operator
- // for sorting purposes, we consider that a Person object is "less than" another
- // if it's age is less than the other object's age
- bool operator<(const Person& rhs) const
- {
- return (age < rhs.age) ? true : false;
- }
- // overload the > operator
- // for sorting purposes, we consider that a Person object is "greater than" another
- // if it's age is greater than the other object's age
- bool operator>(const Person& rhs) const
- {
- return (age > rhs.age) ? true : false;
- }
- // print the object
- void print()
- {
- cout << name << " " << sex << " " << age << endl;
- }
- // destructor
- ~Person()
- {
- delete []name;
- }
- };
- void print(list<Person> lst, char * name)
- {
- list<Person>::iterator it;
- cout << name << ":" << endl;
- for(it = lst.begin(); it != lst.end(); ++it)
- it->print();
- cout << endl;
- }
- int main()
- {
- list<Person> lst;
- // create some Person objects
- Person p1("Bill Gates", 'M', 50);
- Person p2("Scott Meyers", 'M', 43);
- Person p3("Charles Petzold", 'M', 48);
- Person p4("Christina Dermayr", 'F', 30);
- Person p5("Andrei Neagu", 'M', 22);
- Person p6("Yin Su", 'F', 56);
- Person p7("Georgeta Bills", 'F', 37);
- // add the objects to the list
- lst.push_back(p1);
- lst.push_back(p2);
- lst.push_back(p3);
- lst.push_back(p4);
- lst.push_back(p5);
- lst.push_front(p6);
- lst.push_front(p7);
- print(lst, "lst");
- // sort the list in ascending order
- lst.sort( less<Person>() );
- print(lst, "lst in ascending order");
- // sort the list in descending order
- lst.sort( greater<Person>() );
- print(lst, "lst in descending order");
- // delete the first element from the list
- lst.pop_front();
- print(lst, "lst");
- // clear the list
- lst.clear();
- if(lst.empty())
- cout << "lst is empty" << endl;
- else
- cout << "lst is not empty" << endl;
- return 0;
- // Output
- // lst:
- // Georgeta Bills F 37
- //Yin Su F 56
- // Bill Gates M 50
- // Scott Meyers M 43
- // Charles Petzold M 48
- // Christina Dermayr F 30
- // Andrei Neagu M 22
- //
- // lst in ascending order:
- // Andrei Neagu M 22
- // Christina Dermayr F 30
- // Georgeta Bills F 37
- // Scott Meyers M 43
- // Charles Petzold M 48
- // Bill Gates M 50
- // Yin Su F 56
- //
- // lst in descending order:
- // Yin Su F 56
- // Bill Gates M 50
- // Charles Petzold M 48
- // Scott Meyers M 43
- // Georgeta Bills F 37
- // Christina Dermayr F 30
- // Andrei Neagu M 22
- //
- // lst:
- // Bill Gates M 50
- // Charles Petzold M 48
- // Scott Meyers M 43
- // Georgeta Bills F 37
- // Christina Dermayr F 30
- // Andrei Neagu M 22
- //
- // lst is empty
- }
转载请声明: http://blog.csdn.net/nuptboyzhb/article/details/8120397