zoukankan      html  css  js  c++  java
  • C++ STL——deque


    注:原创不易,转载请务必注明原作者和出处,感谢支持!

    注:内容来自某培训课程,不一定完全正确!

    一 deque容器

    1.1 deque容器基本概念

    如上图所示,双端队列deque是一个双口容器,它可以同时在首尾两边进行插入和删除。

    push_front();	// 头部插入
    pop_front();	// 头部删除
    push_back();	// 尾部插入
    pop_back();		// 尾部删除
    
    front();		// 返回队首元素
    back();			// 返回队尾元素
    
    dq.begin();		// 起始迭代器
    dq.end();		// 终止迭代器
    

    deque是“double-ended queue”的缩写,和vector一样,deque也支持随机存取。vector是单向开口的连续性空间,deque则是一种双向开口的连续性空间,所谓双向开口,意思是可以在头尾两段分别做元素的插入和删除操作,vector当然也可以在头尾两段进行插入和删除操作,但是头部插入和删除操作效率奇差,无法接受。

    deque和vector最大的差异在于:
    (1)deque允许常数时间内对头端进行元素插入和删除操作。
    (2)deque没有容量的概念,因为它是动态的以分段的连续空间组合而成,随时可以增加一段新的空间并链接起来,换句话说,像vector那样“因为旧空间不足而重新分配一块更大的空间,然后再复制元素,释放空间”这样的操作不会发生在deque身上,也因此deque没有必要提供所谓的空间保留功能。

    deque的特性总结如下:
    (1)双端插入和删除元素效率较高
    (2)指定位置插入也会导致数据元素移动,降低效率
    (3)可随机存取,效率高

    如上图所示是deque的内部实现原理示意图。对deque中的元素进行排序一般是选择将deque中的元素拷贝到vector中,在vector中完成排序之后再将排序后的元素拷贝回deque当中。

    1.2 deque构造函数

    // 默认构造形式
    deque<T> dq;
    
    // 构造函数将[beg, end)区间中的元素拷贝给本身
    deque(beg, end)
    
    // 构造函数将n个elem拷贝给本身
    deque(n, elem);
    
    // 拷贝构造函数
    deque(const deque &deq);
    

    1.3 deque赋值操作

    // 将[beg, end)区间中的数据拷贝赋值给本身
    assign(beg, end);
    
    // 将n个elem拷贝赋值给本身
    assign(n, elem);
    
    // 重载等号操作符
    deque &operator=(const deque &dep);
    
    // 将deq与本身的元素互换
    swap(dep);
    

    1.4 deque大小操作

    // 返回容器中元素的个数
    deque.size();
    
    // 判断容器是否为空
    deque.empty();
    
    // 重新制定容器长度为num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除
    deque.resize(num);
    
    // 制定填充的默认值
    deque.resize(num);
    

    1.5 deque双端插入和删除操作

    // 在容器尾部和首部插入元素
    push_back(elem);
    push_front(elem);
    
    // 在容器尾部和首部删除元素
    pop_back();
    pop_front();
    

    1.6 deque数据存取

    // 返回索引idx所指的数据,如果idx越界,则抛出out_of_range异常
    at(idx);
    
    // 返回索引idx所指的数据,如果idx越界,不抛出异常,程序
    operator[];
    
    // 返回首部元素
    front();
    
    // 返回末尾元素
    back();
    

    1.7 deque插入和删除

    // 往位置position处插入元素val
    insert(const_iterator position, const valtype &val);
    
    // 清空容器中的元素
    clear();
    
    // 删除[beg, end)区间的数据,返回下一个数据的位置
    erase(beg, end);
    
    // 删除pos位置的数据,返回下一个数据的位置
    erase(pos);
    

    1.8 deque应用案例

    // 选手类型
    class Player
    {
    public:
    	Player() {}
    	Player(string name, int score) : mName(name), mScore(score) {}
    
    public:
    	string mName;
    	int mScore;
    };
    
    // 创建选手
    void CreatePlayer(vector<Player> &v)
    {
    	string nameList = "ABCDE";
    	for (int i = 0; i < 5; ++i)
    	{
    		Player p;
    		p.mName = "选手";
    		p.mName += nameList[i];
    		p.mScore = 0;
    
    		v.push_back(p);
    	}
    }
    
    // 打分
    void SetScore(vector<Player> &v)
    {
    	for (vector<Player>::iterator it = v.begin(); it != v.end(); ++it)
    	{
    		// 10个评委打分
    		deque<int> dScore;
    		for (int i = 0; i < 10; ++i)
    		{
    			int score = rand() % 41 + 60;
    			dScore.push_back(score);
    		}
    
    		// 对分数排序
    		sort(dScore.begin(), dScore.end());
    		// 去除最高和最低分
    		dScore.pop_back();
    		dScore.pop_front();
    		// 求平均分
    		int totalScore = 0;
    		for (deque<int>::iterator dit = dScore.begin(); dit != dScore.end(); ++dit)
    			totalScore += (*dit);
    		int avgScore = totalScore / dScore.size();
    
    		// 保存平均分
    		it->mScore = avgScore;
    	}
    }
    
    // 排序规则
    bool cmp(Player &p1, Player &p2)
    {
    	return (p1.mScore > p2.mScore);
    }
    
    // 得分排名
    void PrintRank(vector<Player> &v)
    {
    	// 从大到小排序
    	sort(v.begin(), v.end(), cmp);
    	for (vector<Player>::iterator it = v.begin(); it != v.end(); ++it)
    	{
    		cout << "name : " << it->mName << " score : " << it->mScore << endl;
    	}
    }
    
    int main()
    {
    	vector<Player> v;
    	CreatePlayer(v);
    	SetScore(v);
    	PrintRank(v);
    
    	getchar();
    	return 0;
    }
    
  • 相关阅读:
    Python有哪些华而不实的技巧?
    json:dumps/loads & pickl
    json模块与第三方模块的引入
    os 及 sys 模块补充
    如何白嫖视频会员
    python和SAS的思考
    5、根据进程号PID查询其服务路径
    5、安装mongodb 异常
    2、shell 判断字符串是否包含另一个字符串
    【九校2D2T1】旋转子段
  • 原文地址:https://www.cnblogs.com/laizhenghong2012/p/11785714.html
Copyright © 2011-2022 走看看