• C++list列表


      

    我想把三个常用的序列式放在一起对比一下是有必要的:

    vector : vector和built-in数组类似,拥有一段连续的内存空间,能非常好的支持随即存取,即[]操作符,但由于它的内存空间是连续的,所以在中间进行插入和删除会造成内存块的拷贝,另外,当插入较多的元素后,预留内存空间可能不够,需要重新申请一块足够大的内存并把原来的数据拷贝到新的内存空间。这些影响了vector的效率,但是实际上用的最多的还是vector容器,建议大多数时候使用vector效率一般是不错的

    list:      list就是数据结构中的双向链表(根据sgi stl源代码),因此它的内存空间是不连续的,通过指针来进行数据的访问,这个特点使得它的随即存取变的非常没有效率,因此它没有提供[]操作符的重载。但由于链表的特点,它可以以很好的效率支持任意地方的删除和插入。

    deque: deque是一个double-ended queue,它的具体实现不太清楚,但知道它具有以下两个特点:它支持[]操作符,也就是支持随即存取,并且和vector的效率相差无几,它支持在两端的操作:push_back,push_front,pop_back,pop_front等,并且在两端操作上与list的效率也差不多。

     因此在实际使用时,如何选择这三个容器中哪一个,应根据你的需要而定,具体可以遵循下面的原则:

    1. 如果你需要高效的随即存取,而不在乎插入和删除的效率,使用vector
    2. 如果你需要大量的插入和删除,而不关心随即存取,则应使用list
    3. 如果你需要随即存取,而且关心两端数据的插入和删除,则应使用deque。

    #include<iostream>
    #include <list>
    
    int main()
    {
        
        std::list<int> l1; //声明一个空列表
        std::list<int> l2(5); //声明一个有n个元素的列表,每个元素都是由其默认构造函数T()构造出来的
        std::list<int> l3(3, 0); //创建含有3个元素的list,值都是0
        std::list<int> l4(l2);    //使用l2初始化l4
        std::list<int> l5(l2.begin(), l2.end());  //同l4
    
        return 0;
    }
    #include<iostream>
    #include <list>
    
    int main()
    {
    
        std::list<int> L;
        for (int i = 0; i < 5; ++i) {
            
            L.push_back(i+10);  //在list的末尾添加一个元素
        }
        std::list<int>::iterator iter; //创建迭代器
        int x=L.front(); //返回第一个元素
        std::cout << x << std::endl;
        x = L.back(); //返回最后一个元素
        std::cout << x << std::endl;
        
        bool b = L.empty();  //判断是否为空
        //如果空  返回真
        std::cout << b << std::endl;
        L.insert(L.begin(), 100); //在L的开始位置插入100
        L.insert(L.begin(),2, 200); //在L的开始位置插入2个200
        //l1.insert(l1.begin(), l2.begin(), l2.end()); 在l1的开始位置插入l2的从开始到结束的所有位置的元素
        L.erase(L.begin()); //将L的第一个元素删除
        //L.erase(L.begin(), L.end()); //将L的从begin()到end()之间的元素删除
        //L.clear();  // 清空list中的所有元素
        L.push_front(1000);//在L的头部位置插入数据
        L.pop_front(); // 删除第一个元素,序列必须不为空
        L.pop_back();  // 删除最后一个元素,序列必须不为空
        L.reverse();  //倒序
    
        for (iter = L.begin(); iter != L.end(); iter++)
            /*
            L.begin()返回第一个元素的迭代器
            L.end()   返回最后一个元素的下一位置的迭代器
            */
            {
            std::cout << *iter << " ";  // *iter   返回指定迭代器的数据
            }
        std::cout << std::endl;
    
        //l1.assign(n, val)将 l1中元素变为n个T(val)
        //l1.assign(l2.begin(),l2.end())将l2中的从l2.begin()到l2.end()之间的数值赋值给l1
        //swap():交换两个表(两个重载),一个是l1.swap(l2); 另外一个是swap(l1,l2),都可能完成连个链表的交换
        //l1.merge(l2,greater<int>());  合并两个表,调用结束后l2变为空,l1中元素包含原来l1 和 l2中的元素,并且排好序,升序,其实默认是升序,greater<int>()可以省略
    
    
    
        return 0;
    }

  • 相关阅读:
    基于C#.NET的Windows进程管理工具
    .NET 中的MD5及hash加密以及密文输出(C#)
    你不一定会的宝宝级数学题
    用C#实现图片文件与base64string编码解码
    怵目惊心的图片
    古鸽和犤毒鸟的故事(扫盲一日)
    office安装问题
    JS 设置与获取Cookie,函数setCookie(name,value,time)getCookie(name)
    JavaScript解码url中的中文字符的方法
    js追加事件FF IE兼容
  • 原文地址:https://www.cnblogs.com/liming19680104/p/13575120.html
Copyright © 2020-2023  润新知