STL-list详解

4.list容器
(1)list的特点
前面讲的vector是非常常用的容器,使用频繁都非常高。

vector的优势:
	vectoer的优点直接导致了它的缺点,因为vector本身就是数组,数组
	是顺序(连续)存储的,因此可以很好的支持随机访问,支持随机访
	问是顺序存储的优势。


vector的缺点:
	在序列中频繁插入和删除的效率非常的低,因为会涉及大片内存数据被
	移动,这也是顺序存储的缺点。


list的优点
	list的优点就是克服了vector的缺点,链表是链式存储的,链式存储的
	优点在于进行频繁插入和删除的效率非常的高,因为链式存储时,链表
	的节点空间并不连续,不会涉及大片内存数据移动。


list的缺点:
	同样,list的有优点直接导致了它的缺点,它不支持随机访问,因为所
	有的节点空间并不是连续的,所以不能跳跃性的随机访问,只能是一个
	一个节点的遍历。



(2)创建一个list		
(1)创建空链表
	std::list data;
	
(2)创建指定元素个数的链表
	std::list data(10);

	链表中内容全部会被初始化为0。

(3)创建一个给定初始值的链表
	(1)所有元素初始值相同的情况
		std::list data(10, 9527);
		10个节点,所有值会被初始化为9527。
		
	(2)所有元素初始值不同的情况	
    		int buf[] = {1, 2, 4, 56, 23, 45, 3, 55};
    		std::list l(buf, buf+sizeof(buf)/sizeof(buf[0]));



(3)访问list容器的元素
(1)如何访问list
	(1)方法1:使用迭代器
		list支持双向迭代器,但双向迭代器不支持随机访问。
		list容器提供正向和逆向两种迭代器,正向迭代器需要使用
		begin()函数和end()成员函数,逆向迭代器需要使用rbegin()和
		rend()成员函数,这一点与vector同。

		由于list不支持随机访问,因此list没有重写[]运算符,就
		算是重写了[]运行算符,实际上也是通过迭代器挨个遍历实
		现的,并不是真正意义上的随机访问。
	
		使用迭代器访问内容时,需要使用*解引用才能访问迭代器指向
		的内容。

	(2)front()和back()函数
		front():直接返回第一个元素内容。
		back()函数直接返回最后一个元素的内容

		以上这两个函数与vector提供的front()和back()函数类似,
		但是由于list不支持随机访问,因此没有at()函数。	
		
(2)例子
	list也有begin()和end()两个成员函数,用于返回访问list的迭代器。
	这个迭代器是由list容器提供的,有了迭代器就可以遍历访问list容
	器。
	
	例子:
	#include 
	#include
	#include

	template void show_vector(iter first, iter last) {

    		for( ;first!=last; first++) {
            		cout << *first << " ";
    		}
    		cout << endl;
	}
		
	int main(void)
	{
    		int buf[] = {1, 2, 4, 56, 23, 45, 3, 55};

    		std::list l1;
    		std::list l2(10);
    		std::list l3(buf, buf+sizeof(buf)/sizeof(buf[0]));

    		cout << "显示l1中的内容" << endl;
    		show_vector(l1.begin(), l1.end());

    		cout << "\n显示l2中的内容" << endl;
    		show_vector(l2.begin(), l2.end());

    		cout << "\n显示l3中的内容" << endl;
    		show_vector(l3.begin(), l3.end());

    		return 0;
	}

	运行结果:
	显示l1中的内容


	显示l2中的内容
	0 0 0 0 0 0 0 0 0 0 

	显示l3中的内容
	1 2 4 56 23 45 3 55 
	
	例子分析:
	例子中分别定义了三个list,然后显示其内容,第一个list是空的
	,因此没有内容被显示。

	第二个list元素个数是10个,但是内容全部被默认初始化为了0。
	
	第三个list在被定义时,被直接初始化了一些值,因此这些值可以
	被打印出来。


(4)使用list容器提供的成员函数实现元素的插入删除等操作
(1)涉及函数
	(1)push_front()函数:在list头部插入新元素
	(2)push_back()函数:在list尾部插入新元素
	(3)pop_front()函数:删除list头部元素
	(4)pop_back()函数:删除list尾部元素
	(5)insert()函数:在list中指定的位置插入新元素,有三个常用的
		重载版本。
		(1)interator insert(iterator position, const T& x);
			在指定位置插入x副本,返回指向该位置的迭代器。

		(2)void insert(iterator position, size_type n, const T& x);
			在指定位置插入n个x的副本。

		(3)void insert(iterator position, InputIterator first, InputIterator last);
			在指定位置插入第二个参数和第三个参数指定的半开间
			隔中的元素,至于InputIterator类型根据情况而定,
			有可能是普通指针也有可能是迭代器。
	(6)ereas()函数:删除指定元素,返回的迭代器指向删除元素后面的元素,
			该函数有两个重载版本。
			(1)iterator erase ( iterator position );
				删除position位置的元素。
			(2)iterator erase ( iterator first, iterator last );		
				删除first与last指定的半开区间之间的元素。
	(7)clear()函数:删除所有元素。
	(8)empty()函数:判断list是否为空。
	(9)slpice()函数:拆分list的函数,该函数提供两个重载版本和一个模板。		
		(1)void splice ( iterator position, list& x );
			将list中内容移到调用splice函数的容器的position处。
		(2)void splice ( iterator position, list& x, iterator i );
			将list中i位置的内容移到调用splice函数的容器的position处。				
		(3)void splice ( iterator position, list& x, iterator first, iterator last );
			将list中[first,last)之间的内容移到调用splice函数的容器的position处。

	(10)resize():设置list的大小
	(11)merge():有两个重载版本,其中一个是模板。
		void merge ( list& x );
		功能:将另外一个list合并到自己中来,合并后进行默认排序。
		template  void merge ( list& x, Compare comp );
		功能:同上,但是可以自己提供比较函数。

		该函数的例子,在后面讲全局merge时意一并举出。			

(2)函数使用举例
	(1)push_front/push_back/pop_front/popback函数使用举例
		#include 
		#include 
		#include
		#include

		template void show_vector(iter first, iter last) {
    			for( ;first!=last; first++) {
            			cout << *first << " ";
    			}
    			cout << endl;
		}

		int main(void)
		{
    			std::list l;

    			cout << "向空l中的头尾插入4个int元素" << endl;
    			l.push_front(1);
    			l.push_back(4);
    			l.push_front(5);
    			l.push_back(3);
    			show_vector(l.begin(), l.end());

    			cout << "\n从l中的头和尾删除2个int元素" << endl;
    			l.pop_front();
    			l.pop_back();
    			show_vector(l.begin(), l.end());

    			return 0;
		}

	(2)insert/ereas/clear/empty函数使用举例
		#include 
		#include 
		#include
		#include

		template void show_vector(iter first, iter last) {
    			for( ;first!=last; first++) {
            			cout << *first << " ";
    			}
    			cout << endl;
		}

		int main(void)
		{
    			int buf[] = {1, 2, 4, 56, 23, 45, 3, 55};
    			std::list l;
			
			if(l.empty()) cout<<"l为空"<
		#include 
		#include
		#include

		template void show_vector(iter first, iter last) {
    			for( ;first!=last; first++) {
            			cout << *first << " ";
    			}
    			cout << endl;
		}

		int main(void)
		{
    			int buf[] = {1, 2, 4, 56, 23, 45, 3, 55};

    			std::list l1(buf, buf+sizeof(buf)/sizeof(buf[0]));
    			std::list l2;

    			cout << "将l1中的所有内容移到l2中begin()开始的位置,移除后l1就为空" << endl;
    			l2.splice(l2.begin(), l1);
    			cout << "l1中的内容" <
#include
#include
#include
#include
#include

using namespace std;
class Student { 
public:
    	Student(const string name=" ", int num=0):name(name),num(num) { } 

    	string getname() const { return name; }
    	int getnum() const { return num; }
private:
    	string name;
    	int num;
}; 

template class List {
public:
    	typedef std::list Content;
    	typedef typename std::list::iterator Iter;

    	List() { }
    	List(Iter first, Iter last):load(first, last) { }

    	void add_list(T* &stu) {load.push_front(stu);}
    	void add_tail(T* &stu) {load.push_back(stu);}
    	void ereas_head() {load.pop_front();}
    	void ereas_tail() {load.pop_back();}

    	void display() {
            	for(Iter iter=load.begin(); iter!=load.end(); iter++) {
                    	cout << (*(iter))->getname() << " " << (*(iter))->getnum() < &list, int count) {
    	string name = "name", newname = "";
    	char buf[10] = {0};
    	int num = 0;
    	srand(time(NULL));
    	for(int i=0; i list;

    	init_stu_list(list, 20);

    	while(1) {
            	cout<<"1. add stu to list" <> select;

            	switch(select) {
                    	case 5: list.display(); break;
                    	default: cout << "未实现" << endl;
            	}
    	}

    	return 0;
}

例子分析:
例子中需要自己利用迭代器实现排序/查找等算法函数,但是实际上c++的STL模板
库提供了现成的全局算法函数。

你可能感兴趣的:(C++)