1. 程式人生 > >[C++ STL] deque使用詳解

[C++ STL] deque使用詳解

一、deque介紹:

deque(雙端佇列)是一個動態陣列,可以向兩端發展,因此不論在尾部或頭部安插元素都十分迅速。 在中間部分安插元素則比較費時,因為必須移動其它元素。


二、用法

1、標頭檔案

#include <deque>
//deque屬於std命名域的,因此需要通過命名限定,例如using std::deque;

2、定義及初始化

deque<int> a; //定義一個int型別的雙端佇列a
deque<int> a(10); //定義一個int型別的雙端佇列a,並設定初始大小為10
deque<int> a(10, 1); //定義一個int型別的雙端佇列a,並設定初始大小為10且初始值都為1
deque<int> b(a); //定義並用向量a初始化雙端佇列b
deque<int> b(a.begin(), a.begin()+3); //將a向量中從第0個到第2個(共3個)作為向量b的初始值

除此之外,還可以直接使用陣列來初始化向量:

int n[] = { 1, 2, 3, 4, 5 };
deque<int> a(n, n + 5);              //將陣列n的前5個元素作為雙端佇列a的初值
//說明:當然不包括arr[4]元素,末尾指標都是指結束元素的下一個元素,
//這個主要是為了和deque.end()指標統一。
deque<int> a(&n[1], &n[4]);        //將n[1]、n[2]、n[3]作為雙端佇列a的初值

3、基本操作

(1) 容量函式

  • 容器大小: deq.size();
  • 容器最大容量: deq.max_size();
  • 更改容器大小: deq.resize();
  • 容器判空: deq.empty();
  • 減少容器大小到滿足元素所佔儲存空間的大小: deq.shrink_to_fit();
#include "stdafx.h"
#include <iostream>
#include <deque>

using namespace std;

int main(int argc, char* argv[])
{
    deque<int> deq;
    for (int i = 0; i<6; i++)
    {
        deq.push_back(i);
    }

    cout << "元素大小: " << deq.size() << endl;
    cout << "元素最大容量: " << deq.max_size() << endl;
    deq.resize(0); //更改元素大小
    cout << "元素大小: " << deq.size() << endl;
    if (deq.empty())
        cout << "元素為空" << endl;

    return 0;
}

/*
元素大小: 6
元素最大容量: 1073741823
元素大小: 0
元素為空
*/

 

(2) 增加函式

  • 頭部新增元素:deq.push_front(const T& x);
  • 末尾新增元素: deq.push_back(const T& x);
  • 任意位置插入一個元素: deq.insert(iterator it, const T& x);
  • 任意位置插入n個相同元素: deq.insert(iterator it, int n, const T& x);
  • 插入另一個向量的[forst,last]間的資料: deq.insert(iterator it, const iterator first, const iterator last);
#include "stdafx.h"
#include <iostream>
#include <deque>

using namespace std;

int main(int argc, char* argv[])
{
    deque<int> deq;

    //頭部增加元素
    deq.push_front(4);
    //末尾新增元素
    deq.push_back(5);
    //任意位置插入一個元素
    deque<int>::iterator it = deq.begin();
    deq.insert(it, 2);
    //任意位置插入n個相同元素
    it = deq.begin(); //必須要有這句
    deq.insert(it, 3, 9);
    //插入另一個向量的[forst,last]間的資料
    deque<int> deq2(5,8);
    it = deq.begin(); //必須要有這句
    deq.insert(it, deq2.end() - 1, deq2.end());

    //display deq
    cout << "deq: ";
    for (it = deq.begin(); it != deq.end(); it++)
        cout << *it << " ";
    cout << endl;

    return 0;
}

/*
deq: 8 9 9 9 2 4 5
*/

 

(3) 刪除函式

  • 頭部刪除元素:deq.pop_front();
  • 末尾刪除元素: deq.pop_back();
  • 任意位置刪除一個元素: deq.erase(iterator it);
  • 刪除[first,last]之間的元素: deq.erase(iterator first, iterator last);
  • 清空所有元素: deq.clear();
#include "stdafx.h"
#include <iostream>
#include <deque>

using namespace std;

int main(int argc, char* argv[])
{
    deque<int> deq;
    for (int i = 0; i < 8; i++)
        deq.push_back(i);

    //頭部刪除元素
    deq.pop_front();
    //末尾刪除元素
    deq.pop_back();
    //任意位置刪除一個元素
    deque<int>::iterator it = deq.begin();
    deq.erase(it);
    //刪除[first,last]之間的元素
    deq.erase(deq.begin(), deq.begin()+1);

    //display deq
    cout << "deq: ";
    for (it = deq.begin(); it != deq.end(); it++)
        cout << *it << " ";
    cout << endl;

    //清空所有元素
    deq.clear();

    //clear, display deq
    cout << "clear,deq: ";
    for (it = deq.begin(); it != deq.end(); it++)
        cout << *it << " ";
    cout << endl;

    return 0;
}

/*
deq: 3 4 5 6
clear,deq:
*/

 

(4) 迭代器

  • 開始迭代器指標:vec.begin();
  • 末尾迭代器指標:vec.end(); //指向最後一個元素的下一個位置
  • 指向常量的開始迭代器指標: vec.cbegin(); //意思就是不能通過這個指標來修改所指的內容,但還是可以通過其他方式修改的,而且指標也是可以移動的。
  • 指向常量的末尾迭代器指標: vec.cend();
  • 反向迭代器指標,指向最後一個元素: rbegin();
  • 反向迭代器指標,指向第一個元素的前一個元素: rend();
#include "stdafx.h"
#include <iostream>
#include <vector>

using namespace std;

int main(int argc, char* argv[])
{
    vector<int> vec;
    vec.push_back(1);
    vec.push_back(2);
    vec.push_back(3);

    cout << "*(vec.begin()): " << *(vec.begin()) << endl;
    cout << "*(vec.end()): " << *(--vec.end()) << endl;
    cout << "*(vec.cbegin()): " << *(vec.cbegin()) << endl;
    cout << "*(vec.cend()): " << *(--vec.cend()) << endl;
    cout << "*(vec.rbegin()): " << *(vec.rbegin()) << endl;
    cout << "*(vec.rend()): " << *(--vec.rend()) << endl;
    cout << endl;

    return 0;
}

/*
*(vec.begin()): 1
*(vec.end()): 3
*(vec.cbegin()): 1
*(vec.cend()): 3
*(vec.rbegin()): 3
*(vec.rend()): 1
*/

 

(5) 訪問函式

  • 下標訪問: vec[1]; //並不會檢查是否越界
  • at方法訪問: vec.at(1); //以上兩者的區別就是at會檢查是否越界,是則丟擲out of range異常
  • 訪問第一個元素: vec.front();
  • 訪問最後一個元素: vec.back();
  • 返回一個指標: int* p = vec.data(); //可行的原因在於vector在記憶體中就是一個連續儲存的陣列,所以可以返回一個指標指向這個陣列。這是是C++11的特性。
#include "stdafx.h"
#include <iostream>
#include <vector>

using namespace std;

int main(int argc, char* argv[])
{
    vector<int> vec;
    for (int i = 0; i < 6; i++)
        vec.push_back(i);

    //下標訪問
    cout << "下標訪問: " << vec[0] << endl;
    //at方法訪問
    cout << "at方法訪問: " << vec.at(0) << endl;
    //訪問第一個元素
    cout << "訪問第一個元素: " << vec.front() << endl;
    //訪問最後一個元素
    cout << "訪問最後一個元素: " << vec.back() << endl;
    //返回一個指標
    int *p = vec.data();
    cout << "指標指向元素: " << *p <<endl;

    return 0;
}

/*
下標訪問: 0
at方法訪問: 0
訪問第一個元素: 0
訪問最後一個元素: 5
指標指向元素: 0
*/

 

(6) 其他函式

  • 多個元素賦值: deq.assign(int nSize, const T& x); //類似於初始化時用陣列進行賦值
  • 交換兩個同類型容器的元素: swap(deque&);
#include "stdafx.h"
#include <iostream>
#include <deque>

using namespace std;

int main(int argc, char* argv[])
{
    //多個元素賦值
    deque<int> deq;
    deq.assign(3,1);
    deque<int> deq2;
    deq2.assign(3, 2);

    //交換兩個容器的元素
    swap(deq,deq2);

    //display deq
    cout << "deq: ";
    for (int i = 0; i < deq.size(); i++)
        cout << deq[i] << " ";
    cout << endl;

    //display deq2
    cout << "deq2: ";
    for (int i = 0; i < deq2.size(); i++)
        cout << deq2[i] << " ";
    cout << endl;

    return 0;
}

/*
deq: 2 2 2
deq2: 1 1 1
*/

 

(7) 演算法

  • 遍歷元素
vector<int>::iterator it;
for (it = vec.begin(); it != vec.end(); it++)
    cout << *it << endl;
//或者
for (int i = 0; i < vec.size(); i++) {
    cout << vec.at(i) << endl;
}
  • 元素翻轉
#include <algorithm>
reverse(vec.begin(), vec.end());
  • 元素排序
#include <algorithm>
sort(vec.begin(), vec.end()); //採用的是從小到大的排序
//如果想從大到小排序,可以採用先排序後反轉的方式,也可以採用下面方法:
//自定義從大到小的比較器,用來改變排序方式
bool Comp(const int& a, const int& b) {
    return a > b;
}
sort(vec.begin(), vec.end(), Comp);


三、總結

可以看到,deque 與 vector 的用法基本一致,除了以下幾處不同:

  • deque沒有capacity()這個成語函式,而vector有。


參考文獻:

longshengguoji-CSDN部落格