1. 程式人生 > 其它 >C++ STL序列式容器

C++ STL序列式容器

序列式容器

vector list deque

0. 迭代器

前向迭代器

支援++p,*p等操作

雙向迭代器

支援--p等操作哦

隨機訪問迭代器

p+=i 迭代器往後移動i個元素

p+i 返回迭代器後第i個元素的迭代器

p[i] 返回p後面第i個元素的引用

迭代器定義方式 具體格式
正向迭代器 容器類名::iterator 迭代器名;
常量正向迭代器 容器類名::const_iterator 迭代器名;
反向迭代器 容器類名::reverse_iterator 迭代器名;
常量反向迭代器 容器類名::const_reverse_iterator 迭代器名;

通過迭代器遍歷

for(i=v.begin();i<v.end();++i){
    cout<<*i<<endl;
}

array<T,N>(陣列容器),儲存N個T型別的元素,長度初始化後不可變

vector,向量容器存放T型別的元素,長度可變,末尾新增刪除元素效率高,隨機訪問效率低

deque,雙端佇列容器,可以在頭部、尾部插入刪除元素

list,連結串列容器,雙向連結串列,長度可變,可以在任何地方新增刪除元素,訪問元素較慢

forward_list,正向連結串列容器,單向連結串列,只能從第一個元素開始訪問,比list快,節省記憶體

array,vector,deque常見函式

函式 功能
begin 指向容器中第一個元素的迭代器
end 指向容器中最後一個元素所在位置的後一個位置的迭代器
rbegin 指向最後一個元素的迭代器
rend 指向容器中第一個元素所在位置的前一個位置的迭代器
cbegin/crbegin 功能同上,增加了const屬性,不可修改
cend/crend 功能同上,增加了const屬性,不可修改
assign 用新元素替換原有內容
size 返回元素個數
capacity 返回容量(vector)
empty 返回容器==空
resize 改變實際元素個數
front 返回第一個元素的引用
back 返回最後一個元素的引用
operator 索引訪問
at 返回一個指向位置n的元素的引用
push_back 在序列尾新增元素
insert 指定元素新增元素
emplace 在指定位置生成元素
emplace_back 在序列尾部生成元素
pop_back 移除序列尾部元素
earse 移除一個或一段元素
clear 清空容器
swap 交換容器內兩個元素
data 返回指向容器中的第一個元素的指標
before_begin 返回指向第一個元素前一個位置的迭代器(forward_list)
push_front 序列起始位置新增一個元素
insert_after 在指定位置後插入一個元素(forward_list)
pop_front 移除序列頭部元素(list,forward_list)
earse_after 移除指定位置後面的一個元素或一段元素。(list,forward_list)
remove 移除所有和引數匹配的元素。
remove_if 移除滿足條件的元素
unique 移除所有連續重複的元素。
sort 排序(list,forward_list)
merge 合併兩個有序容器
splice 移動指定位置前面的所有元素到另一個同類型的 list 中
splice_after 移動指定位置後面的所有元素到另一個同類型的 list 中

1.STL array

聲明後長度不可變

array<typename T,size_t N>
array<double,10> arr{};//不指定值,預設為0
array<double, 10> values {0.5,1.0,1.5,,2.0};//剩餘元素為0
成員函式 功能
begin() 返回指向容器中第一個元素的隨機訪問迭代器。
end() 返回指向容器最後一個元素之後一個位置的隨機訪問迭代器,通常和 begin() 結合使用。
rbegin() 返回指向最後一個元素的隨機訪問迭代器。
rend() 返回指向第一個元素之前一個位置的隨機訪問迭代器。
cbegin() 和 begin() 功能相同,只不過在其基礎上增加了 const 屬性,不能用於修改元素。
cend() 和 end() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用於修改元素。
crbegin() 和 rbegin() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用於修改元素。
crend() 和 rend() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用於修改元素。
size() 返回容器中當前元素的數量,其值始終等於初始化 array 類的第二個模板引數 N。
max_size() 返回容器可容納元素的最大數量,其值始終等於初始化 array 類的第二個模板引數 N。
empty() 判斷容器是否為空,和通過 size()==0 的判斷條件功能相同,但其效率可能更快。
at(n) 返回容器中 n 位置處元素的引用,該函式自動檢查 n 是否在有效的範圍內,如果不是則丟擲 out_of_range 異常。
front() 返回容器中第一個元素的直接引用,該函式不適用於空的 array 容器。
back() 返回容器中最後一個元素的直接應用,該函式同樣不適用於空的 array 容器。
data() 返回一個指向容器首個元素的指標。利用該指標,可實現複製容器中所有元素等類似功能。
fill(val) 將 val 這個值賦值給容器中的每個元素。
array1.swap(array2) 交換 array1 和 array2 容器中的所有元素,但前提是它們具有相同的長度和型別。

array通過[]訪問元素,為了避免越界,可以使用at()成員函式,越界會丟擲out_of_range異常

2.STL vector

vector<double> val;
//擴容,當val.size()>20則不做操作
val.reserve(20);
std::vector<int> primes {2, 3, 5, 7, 11, 13, 17, 19};
std::vector<double> values(20);//指定元素個數,初始為0
std::vector<double> values(20,1);//指定元素個數,初始為1
函式成員 函式功能
begin() 返回指向容器中第一個元素的迭代器。
end() 返回指向容器最後一個元素所在位置後一個位置的迭代器,通常和 begin() 結合使用。
rbegin() 返回指向最後一個元素的迭代器。
rend() 返回指向第一個元素所在位置前一個位置的迭代器。
cbegin() 和 begin() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用於修改元素。
cend() 和 end() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用於修改元素。
crbegin() 和 rbegin() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用於修改元素。
crend() 和 rend() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用於修改元素。
size() 返回實際元素個數。
max_size() 返回元素個數的最大值。這通常是一個很大的值,一般是 232-1,所以我們很少會用到這個函式。
resize() 改變實際元素的個數。
capacity() 返回當前容量。
empty() 判斷容器中是否有元素,若無元素,則返回 true;反之,返回 false。
reserve() 增加容器的容量。
shrink _to_fit() 將記憶體減少到等於當前元素實際所使用的大小。
operator[ ] 過載了 [ ] 運算子,可以向訪問陣列中元素那樣,通過下標即可訪問甚至修改 vector 容器中的元素。
at() 使用經過邊界檢查的索引訪問元素。
front() 返回第一個元素的引用。
back() 返回最後一個元素的引用。
data() 返回指向容器中第一個元素的指標。
assign() 用新元素替換原有內容。
push_back() 在序列的尾部新增一個元素。
pop_back() 移出序列尾部的元素。
insert() 在指定的位置插入一個或多個元素。並返回新插入元素所在位置的迭代器
erase() 移出一個元素或一段元素。,根據索引刪除,
clear() 移出所有的元素,容器大小變為 0。
swap() 交換兩個容器的所有元素。
remove() 根據值刪除元素,不會改變容器的大小和容量
emplace() 在指定的位置直接生成一個元素。
emplace_back() 在序列尾部生成一個元素。

訪問元素的方式

vec[n];
vec.at(n);
vec.front();//首元素
vec.back();//尾元素
vec.data();//返回首元素的指標
*(vec.data()+n);
push_back();
emplace_back();

這兩個函式都可以在容器末尾新增元素

push_back新增元素時,會生成一個元素,再將元素移動(或拷貝)至容器中,而emplace_back會

直接在容器末尾生成,因此emplace_back更加高效

iterator insert(pos,elem);//在指定位置之前插入一個元素elem
iterator insert(pos,n,elem);//在指定位置之前插入n個元素elem
iterator insert(pos,first,last);//在pos之前,插入其他容器中[first,last)區域內的所有元素,返回第一個新元素的迭代器的位置
iterator insert(pos,initlist);//在pos之前插入初始化列表的所有元素,返回第一個新元素的迭代器的位置
iterator emplace(const_iterator pos,args);

pos:指定插入元素的位置,args:新插入元素的建構函式對應的多個引數

刪除元素

erase(n);//刪除指定位置的元素
erase(first,last);//刪除指定位置[first,last)的元素
remove(pos,n);//從pos開始刪除值為n的元素

remove不會改變容器大小和容量

​ remove() 的實現原理是,在遍歷容器中的元素時,一旦遇到目標元素,就做上標記,然後繼續遍歷,直到找到一個非目標元素,即用此元素將最先做標記的位置覆蓋掉,同時將此非目標元素所在的位置也做上標記,等待找到新的非目標元素將其覆蓋。因此,1,3,3,4,3,5,remove(3)如果將上面程式中 demo 容器的元素全部輸出,得到的結果為 1 4 5 4 3 5

因此刪除指定元素需要和erase搭配

auto it=remove(demo.begin(),demo.end(),3);
demo.erase(it,demo.end());
vector<int> demo{1,2,3};
demo.clear();
//demo.size()=0
//demo.capacity()=6

vector<bool>並不是一個STL容器,也不容納bool

vector<bool> 打包 bool 以節省空間,每個儲存在“vector”中的“bool”佔用一個單獨的bit,而禁止有指向單個位元的指標。

3.STL deque

deque相比vector,可以高效的在容器底部或尾部插入元素,且容器內的元素不一定會放在一段連續記憶體裡

deque<int> dq;//初始化空佇列
deque<int> dq(100);//初始化100個預設值的佇列
deque<int> dq(100,1);//初始化100個1的佇列
函式成員 函式功能
begin() 返回指向容器中第一個元素的迭代器。
end() 返回指向容器最後一個元素所在位置後一個位置的迭代器,通常和 begin() 結合使用。
rbegin() 返回指向最後一個元素的迭代器。
rend() 返回指向第一個元素所在位置前一個位置的迭代器。
cbegin() 和 begin() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用於修改元素。
cend() 和 end() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用於修改元素。
crbegin() 和 rbegin() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用於修改元素。
crend() 和 rend() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用於修改元素。
size() 返回實際元素個數。
max_size() 返回容器所能容納元素個數的最大值。這通常是一個很大的值,一般是 232-1,我們很少會用到這個函式。
resize() 改變實際元素的個數。
empty() 判斷容器中是否有元素,若無元素,則返回 true;反之,返回 false。
shrink _to_fit() 將記憶體減少到等於當前元素實際所使用的大小。
at() 使用經過邊界檢查的索引訪問元素。
front() 返回第一個元素的引用。
back() 返回最後一個元素的引用。
assign() 用新元素替換原有內容。
push_back() 在序列的尾部新增一個元素。
push_front() 在序列的頭部新增一個元素。
pop_back() 移除容器尾部的元素。
pop_front() 移除容器頭部的元素。
insert() 在指定的位置插入一個或多個元素。
erase() 移除一個元素或一段元素。
clear() 移出所有的元素,容器大小變為 0。
swap() 交換兩個容器的所有元素。
emplace() 在指定的位置直接生成一個元素。
emplace_front() 在容器頭部生成一個元素。和 push_front() 的區別是,該函式直接在容器頭部構造元素,省去了複製移動元素的過程。
emplace_back() 在容器尾部生成一個元素。和 push_back() 的區別是,該函式直接在容器尾部構造元素,省去了複製移動元素的過程。

注:建立first容器後,容器進行新增操作,會導致first失效

訪問deque元素

dq[n];//訪問容器的中第n個元素
dq.at(n);//訪問容器的中第n個元素,有邊界控制
dq.front();//訪問dq的首元素
dq.back();//訪問dq的尾元素

4.STL list

list雙向連結串列容器,各元素靠指標維持順序,分別指向前後兩個元素,不能通過索引訪問元素

list<int> l;
list<int> l(10);
list<int> l(10,5);
函式 功能
remove(val) 刪除容器中所有等於 val 的元素。
remove_if() 刪除容器中滿足條件的元素。
unique() 刪除容器中相鄰的重複元素,只保留一個。
merge() 合併兩個事先已排好序的 list 容器,並且合併之後的 list 容器依然是有序的。
sort() 通過更改容器中元素的位置,將它們進行排序。
reverse() 反轉容器中元素的順序。

訪問元素:

l.front();//返回list的第一個元素的引用
l.back();//返回list的最後一個元素的引用

list插入元素:

push_front();
push_back();
emplace_back();
emplace_front();
emplace();//在指定位置生成元素
insert();//在指定位置插入元素
splice();//在指定位置插入其他list容器中的元素

splice 將其他list容器中的元素添加當前list容器中指定位置處。

void splice(iterator pos,list& x);//pos:插入位置,x:另一個list容器
void splice(iterator pos,list& x,iterator i);//將x容器中i指向的元素移動到當前容器中pos指明的位置
void splice(iterator pos,list& x,iterator first,iterator last);//將x容器[first,last)範圍內所有元素移動到當前容器pos位置上。

splice方法會將x容器中的相應元素新增到當前容器,該元素會從x中刪除

unique()

void unique();
void unique(BinaryPredicate);//傳入二元謂詞函式

兩種方式都可去重,第二種可以自定義去重規則

remove_if();//傳入自定義為此函式,刪除滿足條件的元素

5.STL forward_list

C++11新容器,底層為單鏈表結構,資料儲存是分散隨機的。可以在序列任何位置新增和刪除元素。

forward_list只提供前向迭代器,無rbegin,rend等函式

相較於list,消耗記憶體小,空間效率高

forward_list<int> fl;
forward_list<int> fl(10);
forward_list<int> fl(10,5);//初始化10個5
before_begin() 返回一個前向迭代器,其指向容器中第一個元素之前的位置。
begin() 返回一個前向迭代器,其指向容器中第一個元素的位置。
end() 返回一個前向迭代器,其指向容器中最後一個元素之後的位置。
cbefore_begin() 和 before_begin() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用於修改元素。
cbegin() 和 begin() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用於修改元素。
cend() 和 end() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用於修改元素。
empty() 判斷容器中是否有元素,若無元素,則返回 true;反之,返回 false。
max_size() 返回容器所能包含元素個數的最大值。這通常是一個很大的值,一般是 232-1,所以我們很少會用到這個函式。
front() 返回第一個元素的引用。
assign() 用新元素替換容器中原有內容。
push_front() 在容器頭部插入一個元素。
emplace_front() 在容器頭部生成一個元素。該函式和 push_front() 的功能相同,但效率更高。
pop_front() 刪除容器頭部的一個元素。
emplace_after() 在指定位置之後插入一個新元素,並返回一個指向新元素的迭代器。和 insert_after() 的功能相同,但效率更高。
insert_after() 在指定位置之後插入一個新元素,並返回一個指向新元素的迭代器。
erase_after() 刪除容器中某個指定位置或區域內的所有元素。
swap() 交換兩個容器中的元素,必須保證這兩個容器中儲存的元素型別是相同的。
resize() 調整容器的大小。
clear() 刪除容器儲存的所有元素。
splice_after() 將某個 forward_list 容器中指定位置或區域內的元素插入到另一個容器的指定位置之後。
remove(val) 刪除容器中所有等於 val 的元素。
remove_if() 刪除容器中滿足條件的元素。
unique() 刪除容器中相鄰的重複元素,只保留一個。
merge() 合併兩個事先已排好序的 forward_list 容器,並且合併之後的 forward_list 容器依然是有序的。
sort() 通過更改容器中元素的位置,將它們進行排序。
reverse() 反轉容器中元素的順序。

forward_list不提供size函式,如果想獲取長度,採用iterator中的distance函式。

int count=distance(begin(fl),end(fl));
int count=distance(fl.begin(),fl.end());

begin(),end()為STL容器方法,可以獲取容器第一個,最後一個元素的迭代器

begin(),end(),引數可以是普通陣列,可可以是容器,為普通陣列將返回第一個、最後一個元素的指標,為容器返回迭代器。

6.vector自定義排序

  • 過載運算子

    struct Book{
    	int page;
    	string name;
    	bool operator <(const Book& b) const // 升序排序時必須寫的函式
        {
            return page < b.page;
        }
        bool operator >(const Book& b) const // 降序排序時必須寫的函式
        {
            return page > b.page;
        }
    }
    vector<Book> books;
    sort(books.begin(), books.end(), less<Book>());
    
  • 全域性比較函式

    struct Book{
    	int page;
    	string name;
    };
    
    bool lessmark(const Book& b1, const Book& b2)
    {
         return b1.page < b2.page;
    }
    bool greatermark(const Book& b1, const Book& b2)
    {
         return b1.page > b2.page;
    }
    vector<Book> books;
    sort(books.begin(), books.end(), lessmark); //升序排序
    
  • 仿生函式(重寫())

    struct Book{
    	int page;
    	string name;
    };
    class CompLess{
    public:
        bool operator ()(const Book& b1, const Book& b2)
        {
            return b1.page < b2.page;
        }
    };
    class CompGreater{
    public:
        bool operator ()(const Book& b1, const Book& b2)
        {
            return b1.page > b2.page;
        }
    };
    vector<Book> books;
    sort(books.begin(), books.end(), CompLess()); //升序排序