疯子的算法总结(三) STL Ⅱ迭代器(iterator) + 容器
一、迭代器(Iterator)
背景:指針可以用來遍歷存儲空間連續的數據結構,但是對于存儲空間費連續的,就需要尋找一個行為類似指針的類,來對非數組的數據結構進行遍歷。
定義:迭代器是一種檢查容器內元素并遍歷元素的數據類型。
迭代器提供對一個容器中的對象的訪問方法,并且定義了容器中對象的范圍。
迭代器(Iterator)是指針(pointer)的泛化,它允許程序員用相同的方式處理不同的數據結構(容器)。
(1)迭代器類似于C語言里面的指針類型,它提供了對對象的間接訪問。
(2)指針是C語言中的知識點,迭代器是C++中的知識點。指針較靈活,迭代器功能較豐富。
(3)迭代器提供一個對容器對象或者string對象的訪問方法,并定義了容器范圍。
迭代器和指針的區別:
容器和string有迭代器類型同時擁有返回迭代器的成員。如:容器有成員begin和end,其中begin成員復制返回指向第一個元素的迭代器,而end成員返回指向容器尾元素的下一個位置的迭代器,也就是說end指示的是第一個不合法地址,所以end返回的是尾后迭代器。
容器迭代器的使用
每種容器類型都定義了自己的迭代器類型,如vector:vector< int>:: iterator iter;//定義一個名為iter的變量,數據類型是由vector< int>定義的iterator 類型。簡單說就是容器類定義了自己的iterator類型,用于訪問容器內的元素。每個容器定義了一種名為iterator的類型,這種類型支持迭代器的各種行為。
我么們先講一下各種迭代器的類型,在講容器所用的迭代器類型,就可以明白怎么操作。
常見迭代器類型如下:
| p++ | 后置自增迭代器 |
| ++p | 前置自增迭代器 |
| 輸入迭代器 | 操作介紹 |
| *p | 復引用迭代器,作為右值 |
| p=p1 | 將一個迭代器賦給另一個迭代器(迭代器指向地址值) |
| p==p1 | 比較迭代器的相等性(比較地址) |
| p!=p1 | 比較迭代器的不等性 |
| 輸出迭代器 | 操作 |
| *p | 復引用迭代器,作為左值 |
| p=p1 | 將一個迭代器賦給另一個迭代器 |
| 正向迭代器 | 提供輸入輸出迭代器的所有功能 |
| 雙向迭代器 | 操作 |
| –p | 前置自減迭代器 |
| p– | 后置自減迭代器 |
| 隨機迭代器 | |
| p+=i | 將迭代器遞增i位 |
| p-=i | 將迭代器遞減i位 |
| p+i | 在p位加i位后的迭代器 |
| p-i | 在p位減i位后的迭代器 |
| p[i] | 返回p位元素偏離i位的元素引用 |
| p<p1 | 如果迭代器p的位置在p1前,返回true,否則返回false |
| p<=p1 | p的位置在p1的前面或同一位置時返回true,否則返回false |
| p>p1 | 如果迭代器p的位置在p1后,返回true,否則返回false |
| p>=p1 | p的位置在p1的后面或同一位置時返回true,否則返回false |
只有順序容器和關聯容器支持迭代器遍歷,各容器支持的迭代器的類別如下:
| vector | 隨機訪問 | 一種隨機訪問的數組類型,提供了對數組元素進行快速隨機訪問以及在序列尾部進行快速的插入和刪除操作的功能。可以再需要的時候修改其自身的大小 |
| deque | 隨機訪問 | 一種隨機訪問的數組類型,提供了序列兩端快速進行插入和刪除操作的功能。可以再需要的時候修改其自身的大小 |
| list | 雙向 | 一種不支持隨機訪問的數組類型,插入和刪除所花費的時間是固定的,與位置無關。 |
| set | 雙向 | 一種隨機存取的容器,其關鍵字和數據元素是同一個值。所有元素都必須具有惟一值。 |
| multiset | 雙向 | 一種隨機存取的容器,其關鍵字和數據元素是同一個值。可以包含重復的元素。 |
| map | 雙向 | 一種包含成對數值的容器,一個值是實際數據值,另一個是用來尋找數據的關鍵字。一個特定的關鍵字只能與一個元素關聯。 |
| multimap | 雙向 | 一種包含成對數值的容器,一個值是實際數據值,另一個是用來尋找數據的關鍵字。一個關鍵字可以與多個數據元素關聯。 |
| stack | 不支持 | 適配器容器類型,用vector,deque或list對象創建了一個先進后出容器 |
| queue | 不支持 | 適配器容器類型,用deque或list對象創建了一個先進先出容器 |
| priority_queue | 不支持 | 適配器容器類型,用vector或deque對象創建了一個排序隊列 |
二、容器
所有容器都支持自定義數據類型,就是結構體。
(一) vector
使用此容器需在程序前加上頭文件#include< vector >。
vector可理解為變長數組,基于倍增思想。當以已申請vector長度為m時,若實際長度n=m,則申請長度為2m的數組,將內容轉移至新地址上,并釋放舊空間;刪除元素時,若n<=m/4,則釋放一半空間。
vector容器能像數組一樣隨機訪問第i個數a[i],但不支持隨機插入.
具體操作如下:
a.size() //返回實際長度(元素個數),O(1)復雜度a.empty() //容器為空返回1,否則返回0,O(1)復雜度a.clear() //把vector清空a.begin() //返回指向第一個元素的迭代器,*a.begin()與a[0]作用相同a.end() //越界訪問,指向vector尾部,指向第n個元素再往后的邊界a.front() //返回第一個元素的值,等價于*a.begin和a[0]a.back() //返回最后一個元素的值,等價于*--a.end()和a[size()-1]a.push_back(x) //把元素x插入vector尾部a.pop_back() //刪除vector中最后一個元素迭代器使用與指針類似,可如下遍歷整個容器
for ( vector<int>::iterator it=a.begin() ; it!=a.end() ; it++ )queue
循環隊列queue需使用頭文件< queue >
priority_queue
優先隊列priority_queue可理解為一個大根二叉堆,必須定義“小于號”,而int,string本身就能比較。同樣需要頭文件< queue >。
其定義方式與queue相似。
可通過插入元素的相反數取出時再取反,或重載“小于號”的方式實現小根堆,通過懶惰刪除法實現隨機刪除操作。
deque
雙端隊列,是一個支持在兩端高效插入或刪除元素的連續線性存儲空間,可像數組一樣隨機訪問,使用前加頭文件< deque >。
定義方式
deque<類型> 名稱ps:clear復雜度為O(n),其余為O(1)。
set/multiset
兩容器相似,但set為有序集合,元素不能重復,multiset為有序多重集合,可包含若干相等的元素,內部通過紅黑樹實現,支持的函數基本相同,同樣必須定義“小于號”運算符,頭文件為< set >。
其迭代器不支持隨機訪問,支持星號(*)結束引用,僅支持 ++ 、-- 兩個與算術有關的操作。迭代器it++,則指向從小到大排序的結果中排在it下一名的元素,兩操作時間復雜度均為O(log n)。
定義方式
set<int> demo 定義一個類型為int的set容器 struct rec {int a,b,c;bool operator<(const rec&w){if(a==w.a) return b==w.b?c<w.c:b<w.b;return a<w.a;} };set<rec> ob; 一樣所有排序的容器不重載就出錯map/multimap
map/multimap映射容器的元素數據是由一個Key和一個Value成的,key與映照value之間具有一一映照的關系。
map/multimap容器的數據結構也采用紅黑樹來實現的,map插入元素的鍵值不允許重復,類似multiset,multimap的key可以重復。比較函數只對元素的key進行比較,元素的各項數據只能通過key檢索出來。雖然map與set采用的都是紅黑樹的結構,但跟set的區別主要是set的一個鍵值和一個映射數據相等,Key=Value。
map<first,second> a; //map,會按照first(鍵值)排序(查找也是);map/multimap用法
頭文件
map成員函數
begin() //返回指向 map 頭部的迭代器 clear() // 刪除所有元素 count() //返回指定元素出現的次數 empty() // 如果 map 為空則返回 true end() //返回指向 map 末尾的迭代器 erase() // 刪除一個元素 find() // 查找一個元素 insert() //插入元素 key_comp() //返回比較元素 key 的函數 lower_bound() //返回鍵值>=給定元素的第一個位置 max_size() //返回可以容納的最大元素個數 rbegin() //返回一個指向 map 尾部的逆向迭代器 rend() //返回一個指向 map 頭部的逆向迭代器 size() //返回 map 中元素的個數 swap() //交換兩個 map創建map對象
#include<iostream> #include<map> using namespace std; map<int,char>mp;//定義map容器創建結構體map對象
struct student{ int birth; string name; }; int id; typedef map<int,student> Student;// 這里相當于給map<int,student> 起了個別名Student,后續代碼均可以用student代替map<int,student> 使用。插入結構體對象
接上文代碼
棧(stack)
1.定義:
棧是一種只能在某一端插入和刪除數據的特殊線性表。他按照先進先出的原則存儲數據,先進的數據被壓入棧底,最后進入的數據在棧頂,需要讀數據的時候從棧頂開始彈出數據(最后被壓入棧的,最先彈出)。因此棧也稱先進后出表。
允許進行插入刪除操作的一端稱為棧頂,另一端稱為棧底。棧底固定,棧頂浮動。插入元素稱為進棧,刪除一個元素稱為進棧,棧內元素為零稱為空棧。
2.stack成員函數
List
定義:List類表示可通過索引訪問的對象的強類型列表,提供用于對列表進行搜索、排序和操作的方法。
作用:
泛型最常見的用途是泛型集合
我們在創建列表類時,列表項的數據類型可能是int,string或其它類型,如果對列表類的處理方法相同,
就沒有必要事先指定數據類型,留待列表類實例化時再指定。相當于把數據類型當成參數,這樣可以最
大限度地重用代碼,保護類型的安全以及提高性能。
定義 list<類型> 名稱
成員函數
bitset
bitset可看作一個多位二進制數,每8位占用1個字節,相當于采用了狀態壓縮的二進制數組,并支持基本的位運算。一般以32位整數的運算次數為基準估算運行時間,n位bitset執行一次的位運算復雜度可視為n/32,效率較高。頭文件< bitset >。
同樣具有~,&,|,^,<<,>>操作符,==,!=可比較二進制數是否相等
總結
以上是生活随笔為你收集整理的疯子的算法总结(三) STL Ⅱ迭代器(iterator) + 容器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python中index是什么(老猿Py
- 下一篇: 大富翁游戏怎么玩