[C++ STL] deque使用詳解
阿新 • • 發佈:2019-01-12
一、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有。
參考文獻: