1. 程式人生 > >c++ stl list使用總結

c++ stl list使用總結

(一)list簡介:

list不像vector那樣,list的記憶體分配時非連續的,因此,只能通過迭代器來訪問list中的元素。另外,list在頭和尾都可以插入元素

(二)建立一個list1.首先包含list的標頭檔案2.使用標準的std名稱空間#include <list>usingnamespacestd;一下是構造list的不同方法:

[c++ code list1.cpp]

#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
}
(三)訪問輸出list中的值
在list中,由於其記憶體是非連續的,因此不能像vector那樣,用[]操作符取值,只能用迭代器

[c++ code list2.cpp]

#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 
}
(四)向list中插入元素
與vector相比,list除了有push_back()//在尾部插入 和 insert()之外,還有push_front()//即在連結串列的頭部插入

[c++ code list3.cpp]

#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
}
(五)刪除list中的元素
主要有如下函式:pop_back(),pop_front(),erase(),remove(),remove_if(),unique(),clear()<empty()>;
與插入元素相對應,list用pop_back()//在尾部刪除一個元素,pop_front()//在頭部刪除一個元素,erase()刪除任意部位

[c++ code list4.cpp]

#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
}
另外,list還有remove()函式,remove()函式也是刪除一個元素,但是,它的引數是元素的值或者是物件,而不是迭代器.同時,還有remove_if()函式,該函式的引數是一個函式,是一個返回值為bool,引數為元素型別的一個函式。

[c++ code list5.cpp]//注意:該程式在VC6.0下編譯報錯,建議使用g++或gcc。

#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;
}
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
}

另外一個刪除元素的函式式unique()函式,還函式有2中呼叫方式。無引數呼叫的情況下,如果該元素與其前一個元素相同,則刪除之。當然,我們也可以傳遞一個判斷是否相等的一個函式。

[c++ code list6.cpp]//注意:該程式在VC6.0下編譯報錯,建議使用g++或gcc

#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
}
(六)連結串列的長度及重置連結串列的長度
與vector不同的是,list沒有capacity() 和 reserve()函式。list用size獲得連結串列的長度,用resize改變其大小。

[c++ code list7.cpp]

#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
}
(七)反轉一個連結串列
呼叫reverse()函式即可,很簡單,不再舉例。
(八)連結串列元素的排序
用sort()函式進行排序,預設情況下是從小到大,當然,也可以人為地改變。

[c++ code list8.cpp]//注意:該程式在VC6.0下編譯報錯,建議使用g++或gcc

#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
}
(九)交換兩個連結串列
直接呼叫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://www.codeproject.com/Articles/20960/The-complete-guide-to-STL-Part-2-List
轉載請宣告:http://blog.csdn.net/nuptboyzhb/article/details/8120397