学科分类
目录
C++基础

list类模板

list列表实现为一个双向链表,因为同为序列式容器,所以它的对外接口大部分与vector和deque都相同,因此我们学习起来也比较容易。

1、创建对象

list类模板中也实现的了不同的的重载构造函数,因此也可以以不同的方式创建对象,创建对象的几种方式如下所示:

list<T> lt;        //创建一个空的列表对象
list<T> lt(n);      //创建一个列表对象,大小为n
list<T> lt(n, elem);  //创建一个列表对象,包含n个elem元素
list<T> lt(begin, end); //创建一个列表对象,用[begin, end)区间的值为元素赋值
list<T> lt(lt1);     //创建一个列表对象,用另一个对象初始化

创建list列表对象有这五种方式,接下来我们分别用这五种方式来创建list列表对象,代码如下所示:

list<char> lt1;
list<int> lt2(10);
list<float>lt3(10, 1.2);
list<string> lt4(begin, end);
list<float> lt5(lt3);

上述代码分别用五种不同方式创建了五个list列表对象,除了第一种形式,其他四种形式都指定了容器大小;第五种形式其实是一个拷贝构造函数,用一个对象初始化另一个对象。

2、赋值

和vector与deque一样,list列表也提供了assign()函数为列表容器赋值,函数调用如下所示:

lt.assign(n, elem);   //将n个elem元素的值赋值给lt
lt.assign(begin, end); //用[begin, end)区间的值给lt中的元素赋值

在list列表中,assign()函数的用法和在vector与deque容器中一样,这里就不再举例说明。

3、元素访问

因为list列表是由链表实现的,内存区域并不是连续的,所以无法用[]运算符来访问元素,也没有可随机访问元素的at()方法,但它提供了下列函数可以访问容器中的元素:

lt.front();   //返回第一个元素
lt.back();    //返回最后一个元素
lt.begin();   //返回第一个元素的迭代器
lt.end();    //返回指向最后一个元素的下一个迭代器

这几个函数的用法和vector与deque的用法一样,front()与back()函数返回的元素的引用,而begin()与end()函数返回的是相应的迭代器。

4、添加元素

list提供了多个函数向容器中添加元素,函数调用如下所示:

lt.push_back();  //在尾部插入元素
lt.push_front(); //在头部插入元素
lt.insert(pos, elem); //在pos位置上插入元素elem
lt.insert(pos, n, elem); //在pos位置上插入n个元素elem
lt.insert(pos, begin, end); //在pos位置上插入[begin, end)区间的值作为元素

这些函数的用法与deque容器中的用法一样,即list列表容器可以头尾部添加元素也可以从中间添加元素。

5、删除元素

list列表也提供了多个函数从容器中删除元素,可以从头尾部删除元素,也可以删除中间某一个元素,函数调用形式如下所示:

lt.pop_back(); //从尾部删除元素
lt.pop_front(); //从头部删除元素
lt.erase(pos);   //从中间删除元素
lt.erase(begin, end); //删除[begin, end)区间的元素
lt.remove(elem); //从容器中删除所有与elem匹配的元素

前四个函数在deque容器中都已经学习过,相信读者已经能熟练的使用。最后一个remove()函数,它是删除容器中所有与参数elem匹配的元素,接下来我们可以用一个案例来演示这些函数的使用,具体如例1所示。

例1

 1    #include <iostream>
 2    #include <list>
 3    using namespace std;
 4    
 5    template<typename T>
 6    void print(list<T> mylist)  //定义print()函数,输出list容器元素
 7    {
 8            list<T>::iterator it;  //创建list列表的迭代器
 9            for (it = mylist.begin(); it != mylist.end(); it++)
 10                cout << *it << " ";
 11            cout << endl;
 12    }
 13    
 14    int main()
 15    {
 16            list<int> lt;
 17            for (int i = 0; i < 10; i++)
 18                lt.push_back(i + 1);   //向容器中添加元素
 19            cout << "输出list容器中的元素:" << endl;
 20            print(lt);
 21            lt.pop_back(); //删除最后一个元素
 22            lt.push_front(5); //在头部添加元素5
 23        
 24            cout << "再次输出list容器中的元素:" << endl;
 25            print(lt);
 26            lt.remove(5);
 27            cout << "删除5之后,输出list容器中的元素:" << endl;
 28            print(lt);
 29            system("pause");
 30            return 0;
 31    }

运行结果如图1所示。

图1 例1运行结果

在例1中,定义了一个list列表容器,并且定义了一个输出列表元素的函数print()函数,代码17-20行,向lt容器中添加元素并输出,由图1可知,元素添加成功。代码21行删除末尾元素,22行代码在头部添加元素5,然后输出元素,由图1可知,再次输出的list容器元素时末尾的10被删除,头部又新增元素5。代码26行调用remove()函数删除容器中所有的5,由图1可知,5被成功删除。

6、merge()函数与sort()函数

函数merge()可以将两个列表容器合并,函数的功能是把一个list对象作为参数插入到目标list容器中,其调用形式如下所示:

lt.merge(list& lt1);

两个容器合并后,容器中的元素按从小到大排列,而且合并之后,lt1容器会变为一个空的容器。list容器还提供了具有排序功能的成员函数sort(),其函数调用如下所示:

lt.sort();

sort()函数使容器中的元素按从小到大的顺序排列。接下来我们通过一个案例来演示这两个函数的用法,具体如例2所示。

例2

 1    #include <iostream>
 2    #include <list>
 3    using namespace std;
 4    
 5    template<typename T>
 6    void print(list<T> mylist)  //定义print()函数,输出list容器元素
 7    {
 8            list<T>::iterator it;  //创建list列表的迭代器
 9            for (it = mylist.begin(); it != mylist.end(); it++)
 10                cout << *it << " ";
 11            cout << endl;
 12    }
 13    
 14    int main()
 15    {
 16            list<int> lt1, lt2;
 17            lt1.push_back(12);
 18            lt1.push_back(6);
 19            lt1.push_back(32);
 20            lt2.push_front(45);
 21            lt2.push_front(9);
 22            cout << "lt1:";
 23            print(lt1);
 24            cout << "lt2:";
 25            print(lt2);
 26            //对lt1容器排序
 27            lt1.sort();
 28            cout << "lt1排序之后:";
 29            print(lt1);
 30            //合并两个容器
 31            lt1.merge(lt2);
 32            cout << "合并两个容器后:";
 33            print(lt1);
 34            system("pause");
 35            return 0;
 36    }

运行结果如图2所示。

图2 例2运行结果

在例2中,定义了两个list容器lt1与lt2,分别向两个容器中随机添加元素,然后输出两个容器中的元素,第27-29行代码调用sort()函数对lt1容器排序,由图8-10的输出结果可知,lt1中的元素实现了从小到大的排序;代码31行又调用merge()函数将两个list容器合并,由图8-10的输出结果可知,两个容器合并成功,并且合并后的元素是按从小到大的顺序排列的。

7、splic()函数

上面讲解的merge()函数可以合并两个list容器,但它有局限性,合并的元素从打乱顺序重新排列,有时合并两个容器的元素只想直到“插队”,而不想重新“排队”。为此,list提供了另外一个函数splice(),该函数用于连接两个list对象,其调用形式如下所示:

lt.splice(iterator it, list& lt1);
lt.splice(iterator it, list& lt1, iterator first);
lt.splice(iterator it, list& lt1, iterator first, iterator last);

● 第一种形式是将容器lt1插入到迭代器it指示的位置前;

● 第二种形式是将lt1中的元素first(first迭代器指示的元素)插入到迭代器it指示的位置前;

● 第三种形式是将lt1容器中[first, last)区间的元素插入到迭代器it指示的位置前面。

与merge()函数一样,一旦合并完成,则lt1中的元素就是被“移走”,即lt1中不再有这些元素,如第一种形式splic()合并,合并之后,lt1容器就变成一个空的容器。

接下来我们通过修改例2来演示splice()函数的用法,具体如例3所示。

例3

 1    #include <iostream>
 2    #include <list>
 3    using namespace std;
 4    
 5    template<typename T>
 6    void print(list<T> mylist)  //定义print()函数,输出list容器元素
 7    {
 8        list<T>::iterator it;  //创建list列表的迭代器
 9        for (it = mylist.begin(); it != mylist.end(); it++)
 10            cout << *it << " ";
 11        cout << endl;
 12    }
 13    
 14    int main()
 15    {
 16        list<int> lt1, lt2, lt3;
 17        lt1.push_back(12);
 18        lt1.push_back(6);
 19        lt1.push_back(32);
 20        lt2.push_front(45);
 21        lt2.push_front(9);
 22        lt3.push_back(100);
 23        lt3.push_back(2);
 24        lt3.push_back(11);
 25        cout << "lt1:";
 26        print(lt1);
 27        cout << "lt2:";
 28        print(lt2);
 29        cout << "lt3:";
 30        print(lt3);
 31        //调用splice()函数将lt2中的第一个元素插入到lt1末尾
 32        lt1.splice(lt1.end(), lt2, lt2.begin());
 33        cout << "lt1与lt2合并后,lt1: ";
 34        print(lt1);
 35        cout << "lt1与lt2合并后,lt2: ";
 36        print(lt2);
 37        //将lt3容器插入到lt1容器前面
 38        lt1.splice(lt1.begin(), lt3);
 39        cout << "lt1与lt3合并后,lt1: ";
 40        print(lt1);
 41        cout << "lt1与lt3合并后,lt3: ";
 42        print(lt3);
 43        system("pause");
 44        return 0;
 45    }

运行结果如图3所示。

图3 例3运行结果

在例3中,定义了三个list列表容器,然后向其中添加元素,各个容器中元素如图8-11所示。代码32行将lt2容器中的第一个元素9插入到了lt1容器末尾,由图8-11可知,插入成功。代码38行将lt3容器中的所有元素插入到lt1头部,由图3可知,元素插入成功。

点击此处
隐藏目录