縱有疾風起,人生不言棄。本文篇幅較長,如有錯誤請不吝賜教,感謝支持。
💬文章目錄
- 一.deque容器的基本概念
- 二.deque容器常用操作
- ①deque構造函數
- ②deque元素操作
- ③deque賦值操作
- ④deque交換操作
- ⑤deque大小操作
- ⑥deque插入和刪除
一.deque容器的基本概念
vector容器是單向開口的連續內存空間,deque(['dek])則是一種雙向開口的連續線性空間。所謂的雙向開口,意思是可以在頭尾兩端分別做元素的插入和刪除操作,可以理解為數據結構的雙端隊列。當然,vector容器也可以在頭尾兩端插入元素,但是在其頭部操作效率奇差,全部元素都要后移,無法被接受。
?deque容器和vector容器的差異:
- ①deque是雙端隊列,可在容器的頭部和尾部插入或刪除元素。
- ②deque沒有容量的概念,因為它是動態的以分段連續空間組合而成,隨時可以增加一段新的空間并鏈接起來,換句話說,deque不會像vector那樣,”舊空間不足而重新配置一塊更大空間,然后復制元素,再釋放舊空間”這樣的事情在deque身上是不會發生的。deque可以隨時將空間串接在首部或尾部,也因此,deque沒有必須要提供所謂的空間保留(reserve)功能。
?deque容器內部實現原理:
deque容器在邏輯上是一片連續的空間,但這只是一種假象,實際deque是由一段一段的定量的連續空間構成。一旦有必要在deque前端或者尾端增加新的空間,便配置一段連續定量的空間,串接在deque的頭端或者尾端。deque最大的工作就是維護這些分段連續的內存空間的整體性的假象,并提供隨機存取的接口,避開了(1)重新配置空間申請更大空間 (2)原數據復制新空間 (3)釋放原空間三步驟,代價就是復雜的迭代器架構。
既然deque是分段連續內存空間,那么就必須有中央控制,維持整體連續的假象。deque內部存在中央控制器,記錄與維護每段數據緩沖區(存儲數據的空間)的內存地址,緩沖區中存儲真實數據,保證可從容器的頭部與尾部插入或刪除元素。緩沖區才是deque的存儲空間主體。
deque容器的迭代器:
支持隨機訪問的迭代器,可跳躍式訪問容器元素。
二.deque容器常用操作
①deque構造函數
作用:創建deque容器。
注:使用deque容器時,需包含頭文件#include <deque>
函數原型 | 解釋 |
---|---|
deque<T> deq T; | 默認構造形式(顯示實例化) |
deque(beg, end); | 構造函數將[beg, end)區間中的元素拷貝給本身。 |
deque(n, elem); | 有參構造函數,使用n個elem元素進行初始化。 |
deque(const deque &deq); | 拷貝構造函數,使用已有deque對象初始化新的對象。 |
實例:deque構造函數
#include <iostream>
using namespace std;
#include <deque>//包含頭文件
void printdeque(const deque<int>& deq)//形參使用const,避免被修改
{ //const_iterator只讀迭代器for (deque<int>::const_iterator it = deq.begin(); it != deq.end(); ++it){cout << *it<<"|";}cout << endl;
}
void test()
{deque<int> v1 = { 1,2,3 };//采用模板實現類實現(顯示實例化),默認構造函數,deque<int> v2(6, 1);//構造函數將n個elem拷貝給本身。int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };deque<int> v3(arr, arr + sizeof(arr) / sizeof(arr[0]));//將v[begin(), end())區間中的元素拷貝給本身deque<int> v4(v1);//拷貝構造函數,拿另一個vector對象初始化本身printdeque(v1);printdeque(v2);printdeque(v3);printdeque(v4);
}
int main()
{test();return 0;
}
②deque元素操作
作用:通過重載賦值運算符operator[]和成員函數at(int index),對deque容器的單個元素進行讀(作為右值)或寫(作為左值)。
函數原型 | 解釋 |
---|---|
T &operator[](size_t n); | 通過[]訪問元素,如果越界,不拋異常,程序直接掛掉 |
T &at(size_t n); | 通過at方法獲取下標為n的元素,如果n越界,拋出out_of_range異常。 |
T *data(); | 返回容器中動態數組的首地址。 |
const T *data() const; | 返回容器中動態數組的首地址。 |
T &front(); | 返回第一個元素。 |
T &back(); | 返回,最后一個元素。 |
③deque賦值操作
作用:通過重載賦值運算符operator=和成員函數assign(),對deque容器進行賦值。
函數原型 | 解釋 |
---|---|
assign(beg, end); | 拷貝目標deque容器中[begin(), end())區間的元素,對當前deque容器賦值。 |
assign(n, elem); | 將n個elem拷貝賦值給本身。 |
deque&operator=(const deque &deq); | 重載等號操作符 |
swap(deq); | 將deq與本身的元素互換 |
實例:deque賦值操作
#include <iostream>
using namespace std;
#include <deque>//包含頭文件
void printdeque(const deque<int>& deq)//形參使用const,避免被修改
{ //const_iterator只讀迭代器for (deque<int>::const_iterator it = deq.begin(); it != deq.end(); ++it){cout << *it<<"|";}cout << endl;
}
void test()
{deque<int> deq;//尾插法插入元素for (int i = 0; i < 5; i++) {deq.push_back(i);}//遍歷printdeque(deq); //0 1 2 3 4/* 1.重載運算符=賦值 */deque<int> d1;d1 = deq;printdeque(d1); //0 1 2 3 4/* 2.assign()函數,區間拷貝 */deque<int> d2;d2.assign(deq.begin(), deq.end());printdeque(d2); //0 1 2 3 4/* 3.assign()函數,n個elem元素賦值 */deque<int> d3;//5個整型元素6d3.assign(5, 6);printdeque(d3); //6 6 6 6 6
}
int main()
{test();return 0;
}
④deque交換操作
💬表格一覽:
函數原型 | 解釋 |
---|---|
void swap(deque &deq); | 把當前容器與deq交換。 |
實例:deque交換操作
#include <iostream>
using namespace std;
#include <deque>//包含頭文件
void printdeque(const deque<int>& deq)//形參使用const,避免被修改
{ //const_iterator只讀迭代器for (deque<int>::const_iterator it = deq.begin(); it != deq.end(); ++it){cout << *it<<"|";}cout << endl;
}
void test()
{deque<int> deq;//尾插法插入元素for (int i = 0; i < 5; i++) {deq.push_back(i);}//遍歷printdeque(deq); //0 1 2 3 4deque<int> d1;d1.swap(deq);//將deq與本身的元素互換printdeque(d1);
}
int main()
{test();return 0;
}
⑤deque大小操作
作用:操作deque容器的大小(即元素個數)。
函數原型 | 解釋 |
---|---|
bool empty() const; | 判斷容器是否為空。 |
size_t size() const; | 返回容器的實際大小(已使用的空間)。 |
resize(int num); | 重新指定容器的長度為num。若容器變長,則以默認值0填充新位置;若容器變短,則容器末尾超出新長度的元素被刪除。 |
resize(int num, elem); | 重新指定容器的長度為num。若容器變長,則以指定值elem填充新位置;若容器變短,則容器末尾超出新長度的元素被刪除。 |
實例:deque大小操作
#include <iostream>
using namespace std;
#include <deque>//包含頭文件
void printdeque(const deque<int>& deq)//形參使用const,避免被修改
{ //const_iterator只讀迭代器for (deque<int>::const_iterator it = deq.begin(); it != deq.end(); ++it){cout << *it<<"|";}cout << endl;
}
void test()
{deque<int> deq;//尾插法插入元素for (int i = 0; i < 5; i++) {deq.push_back(i);}printdeque(deq); //0 1 2 3 4//empty():判斷容器是否為空cout << (deq.empty() ? "deq為空" : "deq不為空") << endl; //deq不為空//size(); :獲取容器的大小,即元素個數。cout << "deq的大小/元素個數:" << deq.size() << endl; //5//resize(int num);:重新指定容器的長度為num//若容器變長,則以默認值0填充新位置;若容器變短,則容器末尾超出新長度的元素被刪除。deq.resize(10); //長度變大時,使用默認值0填充printdeque(deq); //0 1 2 3 4 0 0 0 0 0deq.resize(3); //長度變小時,容器末尾超出新長度的元素被刪除printdeque(deq); //0 1 2//resize(int num, elem); :重新指定容器的長度為num。//若容器變長,則以指定值elem填充新位置;若容器變短,則容器末尾超出新長度的元素被刪除。deq.resize(8, 6); //長度變大時,使用指定值6填充printdeque(deq); //0 1 2 6 6 6 6 6}
int main()
{test();return 0;
}
注:deque容器不存在容量的概念,即不存在capacity()成員函數。可隨時開辟緩沖區存儲數據。
⑥deque插入和刪除
💬表格一覽:
函數原型 | 解釋 |
---|---|
iterator insert(iterator pos, const T& ele); | 在指定位置插入一個元素ele 返回指向插入元素的迭代器。 |
iterator insert(const_iterator pos, int count,ele); | 迭代器指向位置pos插入count個元素ele.返回指向插入元素的迭代器。 |
void push_front(const T& ele); | 在容器頭部插入一個數據 |
void push_back(const T& ele); | 尾部插入元素ele |
void pop_front(); | 刪除容器第一個數據 |
void pop_back(); | 刪除最后一個元素 |
void clear(); | 清空容器。 |
iterator erase(const_iterator start, const_iterator end); | 刪除迭代器從start到end之間的元素,返回下一個有效的迭代器。 |
iterator erase(const_iterator pos); | 刪除迭代器指向的元素,返回下一個有效的迭代器。 |
實例:deque插入和刪除
#include <iostream>
using namespace std;
#include <deque>//包含頭文件
void printdeque(const deque<int>& deq)//形參使用const,避免被修改
{ //const_iterator只讀迭代器for (deque<int>::const_iterator it = deq.begin(); it != deq.end(); ++it){cout << *it<<"|";}cout << endl;
}
void test()
{deque<int> v;for (int i = 0; i < 5; i++){v.push_back(i + 1);//尾部插入元素}printdeque(v);//1 2 3 4 5v.insert(v.begin() + 1, 2, 100);//在第二個元素插入2個100printdeque(v);//1 100 100 2 3 4 5v.pop_front();//頭部刪除一個元素v.pop_back();//尾部刪除一個元素printdeque(v);//100 100 2 3 4cout << "-------------" << endl;v.erase(v.begin());//刪除第一個元素printdeque(v);//100 2 3 4deque<int>::const_iterator it = v.erase(v.begin() + 1, v.end() - 1);//刪除從第二個元素到倒數第二個元素,返回下一個有效迭代器printdeque(v);//100 4v.insert(it, 66);printdeque(v);//100 66 4v.clear();//清空容器
}
int main()
{test();return 0;
}