zoukankan      html  css  js  c++  java
  • C++ STL(七)容器_list

    list(双向链表):是一个双向链表容器,可以高效的地进行插入和删除元素。

    同前二种序列式容器相比,它不支持随机存取元素,不能使用数组[]和at方式进行访问。

    它对元素的搜寻速度是所有容器中最慢的。

    所需头文件:#include<list>

    构造函数:

     1     list<int> listA; //构造个空的list
     2     list<int> listB(5); //定义有5个int元素的list (listB={0,0,0,0,0})
     3     list<int> listC(5,1);//定义有5个int元素的list,每个元素的值为1 (listC={1,1,1,1,1})
     4     list<int> listD(listC); //通过listC拷贝构造一个listD (listD={1,1,1,1,1})
     5     int nArray[] = {1,2,3};
     6     int nLeng = sizeof(nArray)/sizeof(int);
     7     list<int> listE(nArray, nArray+nLeng); //通过数组拷贝构造一个listE (listE={1,2,3})
     8     //使用迭代器构造
     9     list<int> listDD;
    10     listDD.push_back(1);
    11     listDD.push_back(2);
    12     listDD.push_back(3);
    13     listDD.push_back(4);
    14     listDD.push_back(5);
    15     list<int> dIt(listDD.begin(),listDD.end()); //正向迭代器方式构造list (dIt={1,2,3,4,5})
    16     list<int> dRit(listDD.rbegin(), listDD.rend()); //反向迭代器方式构造list (dRit={5,4,3,2,1})
    17 
    18     //注意:
    19     //begin()与end()配套使用.   正向迭代器
    20     //rbegin()与rend()配套使用. 反向迭代器
    21     //begin()返回指向list第一个元素的迭代器  end()返回指向list最后一个元素+1位置的迭代器
    22     //rbegin()返回指向list最后一个元素的迭代器  rend()返回指向list第一个元素-1位置的迭代器
    23 
    24     return;
    构造函数

    获取大小:

    empty()  返回是否为空

    size()     返回大小

    max_size()  返回所能存储的最大元素个数,这是由系统自动定义的值

    resize()    重新设置size,如果变长,变长的元素部份使用默认值,变短就删除多余的元素

     1     list<int> listA;
     2     bool bEmpty = listA.empty(); //bEmpty = true 是否为空
     3     listA.push_back(1);
     4     listA.push_back(2);
     5     bEmpty = listA.empty(); //bEmpty = false
     6     int nLeng = listA.size();  //nLeng = 2  容器大小
     7     int nMaxSize = listA.max_size(); //nMaxSize = 1073741823 所能存储的最大元素个数,这是由系统自动定义的值
     8 
     9     //resize重新设置size,如果变长,变长的元素部份使用默认值,变短就删除多余的元素.
    10     listA.resize(10);
    11     nLeng = listA.size(); //nLeng = 10 
    12     listA.resize(1);
    13     nLeng = listA.size(); //nLeng = 1
    14 
    15     //注意:deque没有deque中的capacity和reserdE方法
    16     return;
    获取大小

    赋值操作:

    注意不能使用数组[]和at方式进行访问

     1     //使用assign()方式赋值
     2     list<int> listC;
     3     //void assign(size_type _Count, const _Ty& _listAl)
     4     listC.assign(2,6); //给listC赋值二个int型元素,元素值为6 (listC={6,6})
     5     //void assign(_Iter _First, _Iter _Last)
     6     list<int> listD;
     7     listC.assign(listD.begin(),listD.end()); //使用迭代器方式把listD中所有元素赋值给listC (listC={})
     8 
     9     //使用swap()交换方式赋值
    10     list<int> listE(2,3);
    11     list<int> listF(4,4);
    12     listE.swap(listF); //ListE = {4,4,4,4} listF = {3,3}
    13 
    14     return;
    assign()赋值

    增加元素操作:

    push_front()   往头部插入一个元素

    push_back()  往末尾插入一个元素

    insert()  往任意位置插入一个元素,指定位置或者指定区间进行插入,第一个参数都是个迭代器。返回值是指向新元素的迭代器

     1     list<int> listA;
     2     //使用push_front()方式,头部插入元素
     3     listA.push_front(1); //listA = {1}
     4     //使用push_back()方式,末尾插入元素
     5     listA.push_back(2); //listA = {1,2}
     6 
     7     //使用insert()方式插入元素, 第一个参数都是迭代器,返回值是指向新元素的迭代器
     8     list<int>::iterator it;
     9     //iterator insert(const_iterator _Where, const _Ty& _listAl) 指定位置插入
    10     it = listA.insert(listA.begin(),2); //往begin()之前插入一个int元素2 (listA={2,1,2}) 此时it指向第一个元素2
    11     //void insert(const_iterator _Where, size_type _Count, const _Ty& _listAl) 指定位置插入
    12     it = listA.insert(listA.end(),2,3);//往end()之前插入2个int元素3 (listA={2,1,2,3,3}) 此时it指向最后一个元素3
    13     //void insert(const_iterator _Where, _Iter _First, _Iter _Last) 指定区间插入
    14     list<int> listB(3,6);
    15     it = listA.insert(listA.end(),listB.begin(),listB.end()); //把listB中所有元素插入到listA的end()之前 (listA={2,1,2,3,3,6,6,6})
    16     //此时*it=6,指向最后一个元素值为6的元素位置
    push_front()和push_back()和insert()

    删除元素操作:

    pop_front() 从头部删除一个元素

    pop_back()  从末尾删除一个元素

    erase()  从任意位置删除一个元素,指定位置或者指定区间进行删除,第一个参数都是个迭代器。返回值是指向删除后的下一个元素的迭代器

    clear()   清除中所有元素, size=0

     1     list<int> listA;
     2     listA.push_back(1);
     3     listA.push_back(2);
     4     listA.push_back(3);
     5     listA.push_back(4);
     6     listA.push_back(5);
     7     //使用pop_front()方式删除头部元素
     8     listA.pop_front(); //listA={2,3,4,5}
     9     //使用pop_back()方式删除末尾元素
    10     listA.pop_back(); //listA={2,3,4}
    11     //使用erase()方式删除元素,第一个参数都是迭代器,返回值是指向删除后的下一个元素的迭代器
    12     list<int>::iterator it;
    13     //iterator erase(const_iterator _Where) 指定位置删除
    14     it = listA.erase(listA.begin()); //删除Where位置的元素 (listA={3,4}) 此时it指向元素3
    15     //void _Reverse(pointer _First, pointer _Last) 指定区间删除
    16     it = listA.erase(listA.begin(),listA.end()); //把begin()到end()之间的所有元素删除 (listA={})
    17     //此时list中己经没有元素了,迭代器指向的下一个元素就是end()
    18 
    19     //使用clear()方式清除所有元素,size变为0
    20     list<int> listB(5,5);
    21     listB.clear(); //(listB={},size=0)
    22 
    23     return;
    pop_front()和pop_back()和erase()和clear()

    遍历元素操作:

    注意:list不支持随机访问,只能通过迭代器进行遍历

     1     list<int> dd;
     2     dd.push_back(1);
     3     dd.push_back(2);
     4     dd.push_back(3);
     5     dd.push_back(4);
     6     dd.push_back(5);
     7 
     8     //使用正向迭代器方式遍历
     9     list<int>::iterator it;
    10     it = dd.begin();
    11     for (it; it!=dd.end(); ++it)
    12     {
    13         cout<<*it<<" ";
    14     }
    15     cout<<endl;
    16     //使用反向迭代器方式遍历
    17     list<int>::reverse_iterator rit;
    18     rit = dd.rbegin();
    19     for (rit; rit!=dd.rend(); ++rit)
    20     {
    21         cout<<*rit<<" ";
    22     }
    23 
    24     return;
    迭代器方式遍历

    释放内存操作:

    注意:除了vector以外,其它容器使用clear都会自动释放内存,不需要使用空的容器进行swap

    小练习题:

    定义一个int型vector,包含1,3,2,3,3,3,4,3,5,3 

    删除容器中所有等于3的元素,然后剩余元素{1,2,4,5} 每二个元素之间插入6个6

    使用vector deque list, 比较三种序列式容器在随机插入和删除上的性能效率

    1. 先声明相关变量

    1     int nArray[] = {1,3,2,3,3,3,4,3,5,3};
    2     int nLeng = sizeof(nArray)/sizeof(int);
    3     double run_time;
    4     _LARGE_INTEGER time_start;  //开始时间
    5     _LARGE_INTEGER time_over;   //结束时间
    6     double dqFreq;      //计时器频率
    7     LARGE_INTEGER f;    //计时器频率
    8     QueryPerformanceFrequency(&f);
    9     dqFreq=(double)f.QuadPart;
    相关变量

    2. vector代码

     1     //vector
     2     QueryPerformanceCounter(&time_start);   //计时开始
     3 
     4     vector<int> vA(nArray,nArray+nLeng);
     5     vector<int>::iterator itA = vA.begin();
     6     while (itA!=vA.end())
     7     {
     8         if(*itA == 3)
     9         {
    10             itA = vA.erase(itA);
    11         }else
    12         {
    13             ++itA;
    14         }
    15     }
    16 
    17     QueryPerformanceCounter(&time_over);    //计时结束
    18     //乘以1000000把单位由秒化为微秒,精度为1000 000/(cpu主频)微秒
    19     run_time=1000000*(time_over.QuadPart-time_start.QuadPart)/dqFreq;
    20     printf("vector删除花费时间:%fus
    ",run_time);
    21 
    22     QueryPerformanceCounter(&time_start);   //计时开始
    23     //剩余元素{1,2,4,5} 每二个元素之间插入6个6
    24     itA = vA.begin();
    25     while (++itA!=vA.end())
    26     {
    27         for (int i=0; i<6; i++)
    28         {
    29             itA = vA.insert(itA,6);
    30         }
    31         itA += 6;
    32     }
    33     QueryPerformanceCounter(&time_over);    //计时结束
    34     //乘以1000000把单位由秒化为微秒,精度为1000 000/(cpu主频)微秒
    35     run_time=1000000*(time_over.QuadPart-time_start.QuadPart)/dqFreq;
    36     printf("vector插入花费时间:%fus
    ",run_time);
    37 
    38 
    39     //deque
    40     QueryPerformanceCounter(&time_start);   //计时开始
    41 
    42     deque<int> dB(nArray,nArray+nLeng);
    43     deque<int>::iterator itB = dB.begin();
    44     while (itB!=dB.end())
    45     {
    46         if(*itB == 3)
    47         {
    48             itB = dB.erase(itB);
    49         }else
    50         {
    51             ++itB;
    52         }
    53     }
    54     QueryPerformanceCounter(&time_over);    //计时结束
    55     run_time=1000000*(time_over.QuadPart-time_start.QuadPart)/dqFreq;
    56     printf("deque删除花费时间:%fus
    ",run_time);
    57 
    58     QueryPerformanceCounter(&time_start);   //计时开始
    59     itB = dB.begin();
    60     while (++itB!=dB.end())
    61     {
    62         for (int i=0; i<6; i++)
    63         {
    64             itB = dB.insert(itB,6);
    65         }
    66         itB += 6;
    67     }
    68 
    69     QueryPerformanceCounter(&time_over);    //计时结束
    70     run_time=1000000*(time_over.QuadPart-time_start.QuadPart)/dqFreq;
    71     printf("deque插入花费时间:%fus
    ",run_time);
    vector

    3.deque代码

     1 //deque
     2     QueryPerformanceCounter(&time_start);   //计时开始
     3 
     4     deque<int> dB(nArray,nArray+nLeng);
     5     deque<int>::iterator itB = dB.begin();
     6     while (itB!=dB.end())
     7     {
     8         if(*itB == 3)
     9         {
    10             itB = dB.erase(itB);
    11         }else
    12         {
    13             ++itB;
    14         }
    15     }
    16     QueryPerformanceCounter(&time_over);    //计时结束
    17     run_time=1000000*(time_over.QuadPart-time_start.QuadPart)/dqFreq;
    18     printf("deque删除花费时间:%fus
    ",run_time);
    19 
    20     QueryPerformanceCounter(&time_start);   //计时开始
    21     itB = dB.begin();
    22     while (++itB!=dB.end())
    23     {
    24         for (int i=0; i<6; i++)
    25         {
    26             itB = dB.insert(itB,6);
    27         }
    28         itB += 6;
    29     }
    30 
    31     QueryPerformanceCounter(&time_over);    //计时结束
    32     run_time=1000000*(time_over.QuadPart-time_start.QuadPart)/dqFreq;
    33     printf("deque插入花费时间:%fus
    ",run_time);
    deque

    4.list代码

     1     //list
     2     QueryPerformanceCounter(&time_start);
     3 
     4     list<int> listC(nArray,nArray+nLeng);
     5     list<int>::iterator itC = listC.begin();
     6     while (itC!=listC.end())
     7     {
     8         if(*itC == 3)
     9         {
    10             itC = listC.erase(itC);
    11         }else
    12         {
    13             ++itC;
    14         }
    15     }
    16     QueryPerformanceCounter(&time_over);    //计时结束
    17     run_time=1000000*(time_over.QuadPart-time_start.QuadPart)/dqFreq;
    18     printf("list删除花费时间:%fus
    ",run_time);
    19 
    20     QueryPerformanceCounter(&time_start);
    21     itC = listC.begin();
    22     while (++itC!=listC.end())
    23     {
    24         for (int i=0; i<6; i++)
    25         {
    26             listC.insert(itC,6);
    27         }
    28     }
    29 
    30     QueryPerformanceCounter(&time_over);
    31     run_time=1000000*(time_over.QuadPart-time_start.QuadPart)/dqFreq;
    32     printf("list插入花费时间:%fus
    ",run_time);
    list

    输出结果:

    ps:这里因为计算的时间片很短,使用了高精度计时器方便比较

    总结:从输出结果可以看出在任意位置(除了头部和尾部)删除和插入元素上,list效率最高,vector和deque差不多

  • 相关阅读:
    DevExpress VCL for Delphi 各版本收集下载
    Delphi XE 5,Rad Studio XE 5 官方下载(附破解),更新 Update 1,Help Update 1
    PostMessage 向Windows窗口发送Alt组合键
    Windows XP UDF 2.5 补丁,播放蓝光ISO光盘必备
    60个开发者不容错过的免费资源库
    [转]游戏多开的原理
    Delphi加载驱动
    窗口截图
    Drectx 3D窗口后台截图
    利用进程ID获取主线程ID
  • 原文地址:https://www.cnblogs.com/fzxiaoyi/p/12102486.html
Copyright © 2011-2022 走看看