【STL】list容器使用与模拟

来源:互联网 发布:c语言循环移位 编辑:程序博客网 时间:2024/06/05 15:29

STL里的list容器里实现了许多接口,list也是我们最常用的容器之一,所以有必要熟练的运用这些接口

1.定义链表的几种方式

 std::list<int> first;                                // 构造一个空链表  std::list<int> second (4,100);                       // 构造一个有四个整形结点的链表  std::list<int> third (second.begin(),second.end());  // 使用左闭右开的迭代器区间进行构造  std::list<int> fourth (third);                       // 调用拷贝构造  // 还可以用数组区间进行构造  int myints[] = {16,2,77,29};  std::list<int> fifth (myints, myints + sizeof(myints) / sizeof(int) );


2.和迭代器有关的几个常用接口


void Testlist(){list<int> s1;s1.push_back(1);s1.push_back(2);s1.push_back(3);s1.push_back(4);s1.push_back(5);//Iterator部分的操作//1.begin & end(配合iterator使用)list<int>::iterator it1 = s1.begin();cout << "正向迭代器打印:";while (it1!=s1.end()){cout<< *it1 <<" ";++it1;}cout << endl;//2.rbegin & rend (配合reverse_iterator使用)list<int>::reverse_iterator rit1 = s1.rbegin();cout << "反向迭代器打印:";while (rit1 != s1.rend()){cout<< *rit1 << " ";++rit1;}cout << endl;


3.和容器容量有关的接口


cout << s1.max_size() << endl;cout << s1.size() << endl;


max_size()返回的是容器的最大容量,等于内存最大容量/结点大小

size()返回容器当前结点的个数

empty()是判断容器是否为空,为空返回true,非空返回false;


4.一些作用容器的算法


//4.void resize (size_type n, value_type val = value_type());cout << "resize:" << endl;print(s1);s1.resize(7,5);//改变list的容量,并把增加的结点插入5print(s1);s1.resize(10); //改变list容量,若没指定插入的值,默认为0print(s1);s1.resize(4);//改变list容量,若是所需容量,则删除后面的结点print(s1);



//5.void remove (const value_type& val);cout << "remove:" << endl;s1.resize(10, 1);print(s1);s1.remove(1);  //删除list里所有的指定的元素print(s1);


/*6.void splice (iterator position, list& x);void splice(iterator position, list& x, iterator i);void splice(iterator position, list& x, iterator first, iterator last);*/cout << "splice:" <<endl ;cout << "s2.splice(s2.begin(), s1);" << endl;list<int> s2;print(s1);         //s :2 3 4print(s2);        //s2:s2.splice(s2.begin(), s1); //把s1链表里的值插入到时s2链表里的begin()前面,并删除s1里的数据print(s1);         //s :print(s2);  //s2:2 3 4cout <<"s1.splice(it1, s2, s2.begin());"<< endl;s1.push_back(10);s1.push_back(20);s1.push_back(30);it1 = s1.begin();++it1;    //it1 指向 20print(s1);                      //s :10 20 30print(s2);                     //s2: 2  3  4 s1.splice(it1, s2, s2.begin()); //在s1链表里元素20的前面插入s2的begin()元素,并删除s2里的begin元素print(s1);   //s  :10 2 20 30print(s2);                     //s2 : 3 4cout << "s2.splice(s2.begin(), s1, it1,s1.end());" << endl;list<int>::iterator it2 = s2.begin();++it2;print(s1);print(s2);s2.splice(s2.begin(), s1, it1,s1.end()); //把s1链表里的20-30这个区间里的值插入到s2链表begin前面print(s1);       print(s2);  



//7.reversecout << "reverse" << endl;print(s2);s2.reverse();  //将链表里的元素逆序打印一遍print(s2);



//8.sortcout << "sort" << endl;s2.sort();    //将链表的元素按照升序排序print(s2);//9.merge 合并链表cout << "merge" << endl;s1.sort();s2.sort();print(s1);print(s2);s1.merge(s2);  //将两个有序链表合并起来,并且合并后也有序,另一个链表被删除print(s1);print(s2);//10.uniquecout << "unique" << endl;s1.push_back(10);print(s1);s1.sort();  s1.unique();  //删除有序链表里重复的值print(s1);

注意:merge和unique都是对有序链表进行操作





5.对容器进行增删改的接口


//12.assigncout << "assign" << endl;print(s1);int a[] = { 1, 2, 3, 4, 5 };s1.assign(a+1 , a + 3);  //重新分配链表里的内容,并重新修改其大小,注意参数是左闭右开区间。print(s1);



//13.void resize (size_type n, value_type val = value_type());调整容器的大小,使其包含n个元素。for (int i = 1; i<10; ++i) s1.push_back(i);print(s1);s1.resize(5);print(s1);s1.resize(8, 100);print(s1);s1.resize(12);print(s1);


//emplace操作是C++11新特性

新引入的的三个成员emlace_front、empace 和 emplace_back,这些操作构造而不是拷贝元素到容器中,这些操作分别对应push_front、insert 和push_back,允许我们将元素放在容器头部、一个指定的位置和容器尾部。

例子 

假定d是一个Date类型的容器。 

//使用三个参数的Date构造函数,在容器管理的内存空间中构造新元素。 d.emplace_back(“2016”,”05”,”26”);//错误,push_back没有这种用法 d.push_back(“2016”,”05”,”26”);//push_back()创建一个临时对象,然后将临时对象拷贝到容器中 d.push_back(Date(“2016”,”05”,”26”));

通过例子发现,使用C++11新特性emplace向容器中添加新元素,在容器管理的内存空间中构造新元素,与insert相比,省去了构造临时对象,减少了内存开销。

两者的区别 
当调用insert时,我们将元素类型的对象传递给insert,元素的对象被拷贝到容器中,而当我们使用emplace时,我们将参数传递元素类型的构造函函数,emplace使用这些参数在容器管理的内存空间中直接构造元素。

注意:emplace函数在容器中直接构造元素,传递给emplace函数的参数必须与元素类型的构造函数相匹配。


//insert()

single element (1)

iterator insert (iterator position, const value_type& val);
fill (2)
    void insert (iterator position, size_type n, const value_type& val);
range (3)
template <class InputIterator>    void insert (iterator position, InputIterator first, InputIterator last);

position代表迭代器指针

val代表要插入的值

n代表插入几个val

first和last代表左闭右开的迭代器区间,可以把其他容器的值插入本容器

        list<int> mylist;list<int>::iterator it = mylist.begin();vector<int> myvector(5, 10);mylist.insert(it, myvector.begin(), myvector.end());print(mylist);  // 正向迭代器打印:10 10 10 10 10

其他一些比较熟悉的增删改的接口,就不演示了。

模拟stl里的list代码:github







原创粉丝点击