• STL之list容器


    摘要:本文主要介绍了list容器的相关内容。

    1、基本概念

    1.1 链表的简单介绍

    链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。

    相较于vector的连续线性空间,list就显得复杂许多,它的好处是每次插入或者删除一个元素,就是配置或者释放一个元素的空间。因此,list对于空间的运用有绝对的精准,一点也不浪费。而且,对于任何位置的元素插入或元素的移除,list都是可以做到的。

    1.2 链表的特点

    • 采用动态存储分配,不会造成内存浪费和溢出
    • 链表执行插入和删除操作十分方便,修改指针即可,不需要移动大量元素
    • 链表灵活,但是空间和时间额外耗费较大

    2、list容器的迭代器

    List容器不能像vector一样以普通指针作为迭代器,因为其节点不能保证在同一块连续的内存空间上。List迭代器必须有能力指向list的节点,并有能力进行正确的递增、递减、取值、成员存取操作。所谓”list正确的递增,递减、取值、成员取用”是指,递增时指向下一个节点,递减时指向上一个节点,取值时取的是节点的数据值,成员取用时取的是节点的成员。

    由于list是一个双向链表,迭代器必须能够具备前移、后移的能力,所以list容器提供的是Bidirectional Iterators.

    List有一个重要的性质,插入操作和删除操作都不会造成原有list迭代器的失效。这在vector是不成立的,因为vector的插入操作可能造成记忆体重新配置,导致原有的迭代器全部失效,甚至List元素的删除,也只有被删除的那个元素的迭代器失效,其他迭代器不受任何影响。

    3、常用API

      API 意义
    构造函数    list<T> lstT 采用采用模板类实现,对象的默认构造形式

                list(beg,end)

     构造函数将[beg, end]区间中的元素拷贝给本身
     list(n,elem)  构造函数将n个elem拷贝给本身
     list(const list &lst)  拷贝构造函数
    数据元素插入和删除操作  push_back(elem)  在容器尾部加入一个元素
    pop_back() 删除容器中最后一个元素
    push_front(elem) 在容器开头插入一个元素
    pop_front() 从容器开头移除第一个元素
    insert(pos,elem) 在pos位置插elem元素的拷贝,返回新数据的位置
    insert(pos,n,elem) 在pos位置插入n个elem数据,无返回值
    insert(pos,beg,end) 在pos位置插入[beg,end)区间的数据,无返回值
    clear() 移除容器的所有数据
    erase(beg,end) 删除[beg,end)区间的数据,返回下一个数据的位置
    erase(pos) 删除pos位置的数据,返回下一个数据的位置
    remove(elem) 删除容器中所有与elem值匹配的元素
    大小操作

              size()

     返回容器中元素的个数
    empty() 判断容器是否为空
    resize(num)

    重新指定容器的长度为num,若容器变长,则以默认值填充新位置。

    如果容器变短,则末尾超出容器长度的元素被删除

    resize(num, elem)

    重新指定容器的长度为num,若容器变长,则以elem值填充新位置。

    如果容器变短,则末尾超出容器长度的元素被删除
    赋值操作  assign(beg, end);  将[beg, end)区间中的数据拷贝赋值给本身
    assign(n, elem) 将n个elem拷贝赋值给本身
    list& operator=(const list &lst) 重载等号操作符
    swap(lst) 将lst与本身的元素互换
    数据的存取  front()  返回第一个元素
    back() 返回最后一个元素
    反转排序  reverse()  反转链表,比如lst包含1,3,5元素,运行此方法后,lst就包含5,3,1元素
    sort() list排序

    4、代码示例

      1 #define _CRT_SECURE_NO_WARNINGS
      2 #include<iostream>
      3 #include<list>
      4 #include <algorithm>
      5 #include <string>
      6 
      7 using namespace std;
      8 
      9 void printList(list<int>&L) {
     10     for (list<int>::iterator it = L.begin(); it != L.end();it++) {
     11         cout << *it << " ";
     12     }
     13     cout << endl;
     14 }
     15 
     16 void test01() {    //初始化,打印
     17     list<int>L1(10,10);
     18     list<int>L2(L1.begin(),L1.end());
     19     printList(L1);
     20     printList(L2);
     21     L2.push_back(100);
     22     printList(L2);
     23 
     24     //逆序打印
     25     for (list<int>::reverse_iterator it=L2.rbegin();it!=L2.rend();it++)
     26     {
     27         cout << *it <<" ";
     28     }
     29        cout << endl;
     30 
     31        list<int>L3; //首尾插入元素
     32        L3.push_back(10);
     33        L3.push_back(20);
     34        L3.push_back(30);
     35        L3.push_front(100);
     36        L3.push_front(200);
     37        L3.push_front(300);
     38 
     39        printList(L3);
     40        L3.pop_front();  //删除头部和尾部
     41        L3.pop_back();
     42        printList(L3);
     43 
     44        L3.insert(L3.begin(), 1000);  //指定位置插入
     45        printList(L3);
     46 
     47        L3.remove(10);  //去除10这个元素
     48        printList(L3);
     49 }
     50 
     51 void test02() {    //容量大小的改变
     52     list<int>L4;
     53     L4.push_back(10);
     54     L4.push_back(20);
     55     L4.push_back(30);
     56     L4.push_front(100);
     57     L4.push_front(200);
     58     L4.push_front(300);
     59     cout << L4.size() << endl;  //输出大小
     60     if (L4.empty())
     61     {
     62         cout << "链表为空" << endl;
     63     }
     64     else {
     65         cout << "链表不为空" << endl;
     66     }
     67 
     68     L4.resize(10);   //扩充补0
     69     printList(L4);
     70 
     71     L4.resize(3);    //只留3个
     72     printList(L4);
     73 
     74     list<int>L5;
     75     L5.assign(L4.begin(), L4.end());
     76     printList(L5);
     77 
     78     cout << L5.front() << endl;
     79     cout << L5.back() << endl;
     80 }
     81 
     82 bool mycompare(int v1,int v2) {
     83     return v1 > v2;
     84 }
     85 
     86 void test03() {   //反转、排序
     87     list<int>L;
     88     L.push_back(10);
     89     L.push_back(50);
     90     L.push_back(20);
     91     L.push_back(60);
     92 
     93     L.reverse();  //进行了反转
     94     printList(L);
     95 
     96     L.sort();  //进行了从小到大的排列
     97     printList(L);
     98 
     99     L.sort(mycompare);  //进行了从大到小的排列
    100     printList(L);
    101 }
    102 
    103 class Person {
    104 public:
    105     string m_name;
    106     int m_age;
    107     int m_height;
    108     Person(string name,int age,int height):m_name(name),m_age(age),m_height(height) {}
    109     
    110     //重载 == 让remove 可以删除自定义的person类型
    111     bool operator==(const  Person & p)
    112     {
    113         if (this->m_name == p.m_name && this->m_age == p.m_age && this->m_height == p.m_height)
    114         {
    115             return true;
    116         }
    117         return false;
    118     }
    119 };
    120 
    121 bool mycompareperson(Person &p1,Person &p2) {
    122   if (p1.m_age==p2.m_age)
    123   {
    124       return p1.m_height < p2.m_height;
    125   }
    126   else {
    127       return p1.m_age > p2.m_age;
    128   }
    129 }
    130 
    131 void test04(){
    132     list<Person>L;
    133     Person p1("火男",20,165);
    134     Person p2("亚瑟", 26, 170);
    135     Person p3("诸葛亮", 29, 175);
    136     Person p4("周瑜", 26, 176);
    137     Person p5("李典", 35, 180);
    138     Person p6("不知火舞", 19, 172);
    139     Person p7("后羿", 39, 188);
    140 
    141     L.push_back(p1);
    142     L.push_back(p2);
    143     L.push_back(p3);
    144     L.push_back(p4);
    145     L.push_back(p5);
    146     L.push_back(p6);
    147     L.push_back(p7);
    148 
    149     L.sort(mycompareperson);
    150     for (list<Person>::iterator it=L.begin();it!=L.end();it++)
    151     {
    152         cout << "姓名:  "<< it->m_name <<"年龄:  "<<(*it).m_age<<"身高:  "<<it->m_height<< endl;
    153     }
    154 
    155     L.remove(p6);
    156     for (list<Person>::iterator it = L.begin(); it != L.end(); it++)
    157     {
    158         cout << "姓名:  " << it->m_name << "年龄:  " << (*it).m_age << "身高:  " << it->m_height << endl;
    159     }
    160 }
    161 
    162 int main() {
    163     //test01();
    164     //test02();
    165     //test03();
    166     test04();
    167     system("pause");
    168     return 0;
    169 }
  • 相关阅读:
    团队协议
    C++ 多继承和虚继承的内存布局(转)
    轻量级的.Net ORM框架介绍
    EF下CodeFirst、DBFirst与ModelFirst分析
    JDK方式
    JSON
    事务的ACID特性
    数据库查询
    Assets
    内部文件存储
  • 原文地址:https://www.cnblogs.com/lzy820260594/p/11385749.html
Copyright © 2020-2023  润新知