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差不多

  • 相关阅读:
    hdu 1042 N!
    hdu 1002 A + B Problem II
    c++大数模板
    hdu 1004 Let the Balloon Rise
    hdu 4027 Can you answer these queries?
    poj 2823 Sliding Window
    hdu 3074 Multiply game
    hdu 1394 Minimum Inversion Number
    hdu 5199 Gunner
    九度oj 1521 二叉树的镜像
  • 原文地址:https://www.cnblogs.com/fzxiaoyi/p/12102486.html
Copyright © 2011-2022 走看看