1. 程式人生 > >STL 迭代器(iterator)詳解

STL 迭代器(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:vector< int>:: iterator iter; //定義一個名為iter的變數,資料型別是由vector< int>定義的iterator 型別。常用迭代器型別如下:

容器 支援的迭代器類別 說明
vector 隨機訪問 一種隨機訪問的陣列型別,提供了對陣列元素進行快速隨機訪問以及在序列尾部進行快速的插入和刪除操作的功能。可以再需要的時候修改其自身的大小
deque 隨機訪問 一種隨機訪問的陣列型別,提供了序列兩端快速進行插入和刪除操作的功能。可以再需要的時候修改其自身的大小
list 雙向 一種不支援隨機訪問的陣列型別,插入和刪除所花費的時間是固定的,與位置無關。
set 雙向 一種隨機存取的容器,其關鍵字和資料元素是同一個值。所有元素都必須具有惟一值。
multiset 雙向 一種隨機存取的容器,其關鍵字和資料元素是同一個值。可以包含重複的元素。
map 雙向 一種包含成對數值的容器,一個值是實際資料值,另一個是用來尋找資料的關鍵字。一個特定的關鍵字只能與一個元素關聯。
multimap 雙向 一種包含成對數值的容器,一個值是實際資料值,另一個是用來尋找資料的關鍵字。一個關鍵字可以與多個數據元素關聯。
stack 不支援 介面卡容器型別,用vector,deque或list物件建立了一個先進後出容器
queue 不支援 介面卡容器型別,用deque或list物件建立了一個先進先出容器
priority_queue 不支援 介面卡容器型別,用vector或deque物件建立了一個排序佇列

如上表所示,迭代器型別主要支援兩類,隨機訪問和雙向訪問。其中vector和deque支援隨機訪問,list,set,map等支援雙向訪問。


二、容器迭代器的使用

下面列舉了些例子說明各個容器的用法:

1、vector

#include "stdafx.h"
#include <iostream>
#include <vector>

using namespace std;

int main(int argc, char* argv[])
{
    // Create and populate the vector
    vector<int> vecTemp;
    for (int i = 0; i<6; i++)
    {
        vecTemp.push_back(i);
    }

    // Display contents of vector
    cout <<"Original deque: ";    
    vector<int>::iterator it;
    for (it = vecTemp.begin(); it!=vecTemp.end(); it++)
    {
        cout <<*it <<" ";
    }

    return 0;
}

/*
輸出結果:
Original deque: 0 1 2 3 4 5
*/

2、deque

#include "stdafx.h"
#include <iostream>
#include <deque>

using namespace std;

int main(int argc, char* argv[])
{
    // Create and populate the deque
    deque<int> dequeTemp;
    for (int i = 0; i<6; i++)
    {
        dequeTemp.push_back(i);
    }

    // Display contents of deque
    cout <<"Original deque: ";
    deque<int>::iterator it;
    for (it = dequeTemp.begin(); it != dequeTemp.end(); it++)
    {
        cout <<*it <<" ";
    }
    cout <<endl;

    return 0;
}
/*
輸出結果:
Original deque: 0 1 2 3 4 5
*/

3、list

#include "stdafx.h"
#include <iostream>
#include <list>

using namespace std;

int main(int argc, char* argv[])
{
    // Create and populate the list
    list<int> listTemp;
    for (int i = 0; i<6; i++)
    {
        listTemp.push_back(i);
    }

    // Display contents of list
    cout << "Original list: ";
    list<int>::iterator it;
    for (it = listTemp.begin(); it != listTemp.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;

    // Insert five 9 into the list
    list<int>::iterator itStart = listTemp.begin();
    listTemp.insert(itStart,5,9);

    // Display the result
    cout << "Result of list: ";
    for (it = listTemp.begin(); it != listTemp.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;

    return 0;
}
/*
輸出結果:
Original list: 0 1 2 3 4 5
Result of list: 9 9 9 9 9 0 1 2 3 4 5
*/

4、set

#include "stdafx.h"
#include <iostream>
#include <set>

using namespace std;

int main(int argc, char* argv[])
{
    // Create and populate the set
    set<char> setTemp;
    for (int i = 0; i<6; i++)
    {
        setTemp.insert('F'-i);
    }

    // Display contents of set
    cout <<"Original set: ";
    set<char>::iterator it;
    for (it = setTemp.begin(); it != setTemp.end(); it++)
    {
        cout <<*it <<" ";
    }
    cout <<endl;

    return 0;
}
/*
輸出結果:
Original set: A B C D E F
*/

5、map

#include "stdafx.h"
#include <iostream>
#include <map>

using namespace std;

typedef map<int, char> MyMap;

int main(int argc, char* argv[])
{
    // Create and populate the map
    MyMap mapTemp;
    for (int i = 0; i<6; i++)
    {
        mapTemp[i] = ('F'-i);
    }

    // Display contents of map
    cout <<"Original map: " <<endl;
    MyMap::iterator it;
    for (it = mapTemp.begin(); it != mapTemp.end(); it++)
    {
        cout << (*it).first << " --> ";
        cout << (*it).second << std::endl;
    }
    cout <<endl;

    return 0;
}
/*
輸出結果:
Original map:
0 --> F
1 --> E
2 --> D
3 --> C
4 --> B
5 --> A
*/