日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

复习笔记(九)——C++中的容器(STL容器)

發布時間:2025/3/21 c/c++ 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 复习笔记(九)——C++中的容器(STL容器) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

STL定義

STL(Standard Template Library),即標準模板庫,是一個高效的C++程序庫。被容納于C++標準程序庫(C++ Standard Library)中,是ANSI/ISO C++標準中最新的也是極具革命性的一部分。包含了諸多在計算機科學領域里常用的基本數據結構和基本算法。為廣大C++程序員們提供了一個可擴展的應用框架,高度體現了軟件的可復用性

從邏輯層次來看,在STL中體現了泛型化程序設計的思想(generic programming)。在這種思想里,大部分基本算法被抽象,被泛化,獨立于與之對應的數據結構,用于以相同或相近的方式處理各種不同情形。

從實現層次看,整個STL是以一種類型參數化(type parameterized)的方式實現的基于模板(template)。

容器分為兩大類:順序容器、關聯容器。

順序容器

順序容器有以下三種:vector(向量)、 deque(雙隊列)、list(列表)。

它們之所以被稱為順序容器,是因為元素在容器中的位置同元素的值無關,即容器不是排序的。將元素插入容器時,指定在什么位置(尾部、頭部或中間某處)插入,元素就會位于什么位置。

順序容器的接口:
①插入方法

push_front()push_back()insert(),運算符“=

②刪除方法

pop()erase()clear()

③迭代訪問方法

使用迭代器

④其他順序容器訪問方法(不修改訪問方法)

front()back(),下標[]運算符

1、vector

向量屬于順序容器,用于容納不定長線性序列(即線性群體),提供對序列的快速隨機訪問(也稱直接訪問)。

數據結構很像一個數組,所以與其他容器相比,vector 能非常方便和高效訪問單個元素,支持隨機訪問迭代子。

向量是動態結構,它的大小不固定,可以在程序運行時增加或減少與數組不同,向量的內存用盡時,向量自動分配更大的連續內存區,將原先的元素復制到新的內存區,并釋放舊的內存區。這是向量類的優點。

頭文件:#include <vector>

基本操作:

(1)頭文件 #include<vector>(2)創建vector對象 vector<int> vec;(3)尾部插入數字 vec.push_back(a);(4)使用下標訪問元素 cout<<vec[0]<<endl;記住下標是從0開始的。(5)使用迭代器訪問元素vector<int>::iterator it;for(it=vec.begin();it!=vec.end();it++)cout<<*it<<endl;(6)插入元素 vec.insert(vec.begin()+i,a);在第i+1個元素前面插入a;(7)刪除元素 vec.erase(vec.begin()+2);刪除第3個元素 vec.erase(vec.begin()+i,vec.end()+j);刪除區間[i,j-1];區間從0開始(8)向量大小 vec.size(); vec.resize;改變大小(9)清空 vec.clear();

示例(輸出質數):

#include <iostream> #include <iomanip> #include <vector> //包含向量容器頭文件 using namespace std ; int main(){vector<int> A(10); //創建vector對象int n;int primecount = 0, i, j;cout<<"Enter a value>=2 as upper limit: ";cin >> n;A[primecount++] = 2;//下標法訪問元素for(i = 3; i < n; i++){if (primecount == A.size())A.resize(primecount + 10); //改變容器大小if (i % 2 == 0)continue;j = 3;while (j <= i/2 && i % j != 0)j += 2;if (j > i/2) A[primecount++] = i;}for (i = 0; i<primecount; i++){//輸出質數cout<<setw(5)<<A[i];if ((i+1) % 10 == 0) //每輸出10個數換行一次cout << endl;}cout<<endl;return 0; }-------------- 執行結果: Enter a value>=2 as upper limit: 202 3 5 7 11 13 17 19

2、deque

雙端隊列是一種放松了訪問權限的隊列。元素可以從隊列的兩端入隊和出隊,也支持通過下標操作符“[]”進行直接訪問。

與向量的對比
功能上:和向量沒有多少區別,
性能上:在雙端隊列起點上的插入和刪除操作快

頭文件:#include <deque>


3、list

列表主要用于存放雙向鏈表,可以從任意一端開始遍歷。列表還提供了拼接(splicing)操作,將一個序列中的元素從插入到另一個序列中。

對比
①元素的插入和刪除操作對 list 而言尤為高效。
②與 vector 和 deque 相比,對元素的下標訪問操作的低效是不能容忍的,因此 list 不提供這類操作。

頭文件:#include <list>

示例

#include <iostream> #include <list> using namespace std ; int main(){list<int> Link; //構造一個列表用于存放整數鏈表int i, key, item;for(i=0;i < 10;i++)// 輸入10個整數依次向表頭插入{Link.push_front(i);}cout<< "List:"; // 輸出鏈表list<int>::iterator p=Link.begin();while(p!=Link.end()){ //輸出各節點數據,直到鏈表尾cout <<*p << " ";p++; //使P指向下一個節點}cout << endl;cout << "請輸入一個需要刪除的整數: ";cin >> key;Link.remove(key);cout << "List: "; // 輸出鏈表p=Link.begin(); // 使P重新指向表頭while(p!=Link.end()){cout <<*p << " ";p++; // 使P指向下一個節點}cout << endl; }--------------------- 執行結果示例: List:9 8 7 6 5 4 3 2 1 0 請輸入一個需要刪除的整數: 3 List: 9 8 7 6 5 4 2 1 0

順序容器的選擇

a、若需要隨機訪問操作,則選擇vector;
b、若已經知道需要存儲元素的數目, 則選擇vector;
c、若需要隨機插入/刪除(不僅僅在兩端),則選擇list
d、只有需要在首端進行插入/刪除操作的時候,才選擇deque,否則都選擇vector。
e、若既需要隨機插入/刪除,又需要隨機訪問,則需要在vector與list間做個折中。
f、當要存儲的是大型負責類對象時,list要優于vector;當然這時候也可以用vector來存儲指向對象的指針,同樣會取得較高的效率,但是指針的維護非常容易出錯,因此不推薦使用。

注意:vector與deque的迭代器支持算術運算,list的迭代器只能進行++/–操作,不支持普通的算術運算。


關聯容器

通過保存在數據項中的索引項,盡可能快速檢索數據項。

STL標準庫中只包含有序關聯容器:set(集合)、multiset(多重集合)、map(映射)、multimap(多重映射)。

set, multiset:數據項就是索引項。 multiset允許出現重復的索引項。
map, multimap:數據項是由索引項和其他某種類型的數據組成的一對數據。 multimap允許出現重復的索引項。


1、map

增加和刪除節點對迭代器的影響很小。對于迭代器來說,可以修改實值,而不能修改key。

自動建立Key-value的對應。key 和 value可以是任意你需要的類型。

根據key值快速查找記錄,查找的復雜度基本是Log(N),如果有1000個記錄,最多查找10次,1,000,000個記錄,最多查找20次。

map的構造函數:

使用map得包含map類所在的頭文件

#include <map>

map對象是模板類,需要關鍵字和存儲對象兩個模板參數:

map<int, string> personnel;//用int作為索引,存儲string對象

示例:

#include <map> #include <iostream> #include <string> using namespace std; int main(){map< string, string > trans_map;typedef map< string, string >::value_type valType;trans_map.insert( valType( "001", "wang" ));trans_map.insert( valType( "002", "li" ));trans_map.insert( valType( "003", "luo" ));trans_map.insert( valType( "004", "wu" ));trans_map.insert( valType( "005", "zhao" ));trans_map.insert( valType( "006", "sun" ));trans_map.insert( valType( "007", "qian" ));trans_map.insert( valType( "008", "long" ));map< string,string >::iterator it;cout << "Here is our transformation map: \n";for(it=trans_map.begin();it!=trans_map.end();++it)cout<<"key: "<<(*it).first<<"\t"<<"value: " <<(*it).second<<"\n";cout<<"Find Key:005"<<endl;it=trans_map.find("005");if (it==trans_map.end()){cout<<"not found"<<endl;}else{cout<<"key: "<<(*it).first <<"\t"<<"value: " <<(*it).second<<"\n";}return 0; }---------------------- 執行結果: Here is our transformation map: key: 001 value: wang key: 002 value: li key: 003 value: luo key: 004 value: wu key: 005 value: zhao key: 006 value: sun key: 007 value: qian key: 008 value: long Find Key:005 key: 005 value: zhao

2、multimap

multimap 除了元素對的關鍵字不是唯一外,與 map 相似

頭文件:#include <map>


3、set

set 可以被視為只有關鍵字而沒有相關的元素值的 map,因此 set 的用戶接口也發生了微小的變化:成員類型中沒有:
①typedef Key value_type;
②typedef Cmp value_compare
③操作中沒有元素的下標訪問操作。

頭文件:#include <set>


4、multiset

multiset 除了關鍵字不是唯一外,與 set 相似。

頭文件:#include <set>


容器的函數

所有容器都有以下兩個成員函數:
int size():返回容器對象中元素的個數。
bool empty():判斷容器對象是否為空。

順序容器和關聯容器還有以下成員函數:
begin():返回指向容器中第一個元素的迭代器。
end():返回指向容器中最后一個元素后面的位置的迭代器。
rbegin():返回指向容器中最后一個元素的反向迭代器。
rend():返回指向容器中第一個元素前面的位置的反向迭代器。
erase(...):從容器中刪除一個或幾個元素。
clear():從容器中刪除所有元素。

如果一個容器是空的,則 begin() 和 end() 的返回值相等,rbegin() 和 rend() 的返回值也相等。

順序容器還有以下常用成員函數:
front():返回容器中第一個元素的引用。
back():返回容器中最后一個元素的引用。
push_back():在容器末尾增加新元素。
pop_back():刪除容器末尾的元素。
insert(...):插入一個或多個元素。該函數參數較復雜,此處省略。

示例

(這里只列舉一些容器以及一些函數用法)
順序容器:
vector 容器

void main() //遍歷、刪除、插入 {vector<int> v1;v1.push_back(10); //copy 到申請的容器v1.push_back(20); v1.push_back(30); //訪問容器,定義一個迭代器: 相當于一個指針//正向遍歷for(vector<int>::iterator it = v1.begin();it != v1.end();it++){cout<<*it<<endl;}//逆向遍歷for(vector<int>::reverse_iterator rit = v1.rbegin();rit != v1.rend();rit++){cout<<*rit<<endl;}//區間刪除v1.erase(v1.begin(),v1.begin()+2);//指定位置刪除v1.erase(v1.begin());//遍歷刪除for(vector<int>::iterator dit = v1.begin();dit != v1.end();){if(*dit == 2){v1.erase(dit); //當刪除迭代器所指向元素時,erase讓it自下移}else{dit++;}}//插入元素v1.insert (v1.begin(),100); //頭部插入數值100v1.insert (v1.end (),200); //尾部插入數值200return; }

deque 容器

void printd(deque<int> &d) {for(deque<int>::iterator it = d.begin(); it != d.end();it++){cout<<"元素"<<*it<<endl;} } void main() {deque<int> d;d.push_back(1); //在容器末尾增加新元素d.push_back(2); d.push_front(3); //在容器頭尾增加新元素d.push_front(4);printd(d);deque<int>::iterator it = find(d.begin(),d.end(),3); //查找指定元素3 找到時,返回該元素的迭代器;找不到時,返回end()。 if(it != d.end()){cout<<"3與第一個元素的距離為:"<<distance(d.begin (),it)<<endl;}}

關聯容器:
set容器

void main() {set<int> set1;//循環插入for(int i = 0;i < 3;i ++){int tmp = rand() % 5;set1.insert(tmp);}//遍歷打印集合for(set<int>::iterator it = set1.begin();it != set1.end(); it++){cout<<*it<<endl;}//刪除集合while(!set1.empty()){set<int>::iterator item = set1.begin();set1.erase(item);}return; }

map容器

//元素的添加、遍歷、刪除等基本操作 void main() {//1、創建map對象map<int, string> map1;//方法1 添加元素 pair是一個有兩個元素的結構體,方便使用,類似map :鍵值可以隨意使用 //pair可以用來當做map的鍵值來插入 pair<T1,T2> p1 創建一個空的pair對象,有兩個元素T1和T2,采用值初始化map1.insert(pair<int, string>(1,"hehe"));map1.insert(pair<int, string>(2,"xixi"));//方法2 添加元素 make_pair//make_pairmap1.insert(make_pair(3,"haha"));map1.insert(make_pair(4,"huhu"));//方法3 添加元素map1.insert(map<int, string>::value_type(5,"kaka"));map1.insert(map<int, string>::value_type(6,"yiyi"));//方法4 數組方式插入數據map1[7] = "yaya";//容器遍歷(迭代器)for(map<int, string>::iterator it = map1.begin();it != map1.end(); it++){cout<<it->first<<"\t"<<it->second <<endl;}cout<<"遍歷結束"<<endl;//容器的刪除while(!map1.empty()){map<int, string>::iterator it = map1.begin();map1.erase(it);}//map查找map<int, string>::iterator it1 = map1.find(2);if(it1 != map1.end()){cout<<"不存在"<<endl;}else{cout<<it1->first<<"\t"<<it1->second<<endl;}} 《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的复习笔记(九)——C++中的容器(STL容器)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。