一、介紹
- 迭代器是一種物件,它能夠用來遍歷標準模板庫容器中的部分或全部元素,每個迭代器物件代表容器中的確定的地址。迭代器修改了常規指標的介面,所謂迭代器是一種概念上的抽象:那些行為上像迭代器的東西都可以叫做迭代器。用迭代器可以很大程度上隔離容器底層實現,使用時只需依賴迭代器相對統一的方法/介面。
- 圖的相鄰節點迭代器 ( adjIterato )是用來高效的對圖相鄰節點遍歷的,能對圖進行操作。
二、實現
- 稠密圖相鄰節點迭代器的實現:
我們需要將此迭代器寫在稠密圖的類中
稠密圖:
#include <iostream>
#include <vector>
#include <cassert>
using namespace std;
//稠密圖
class DenseGraph{
private:
int n, m; //節點數和邊數
bool directed; //是否為有向圖
vector<vector<bool>> g; //圖的具體資料,0 1 用bool值false和true表示
public:
DenseGraph(int n, bool directed){
assert(n >= 0);
this->n = n;
this->m = 0;
this->directed = directed;
// g初始化為n*n的布林矩陣, 每一個g[i][j]均為false, 表示沒有任和邊
g = vector<vector<bool>>(n, vector<bool>(n, false));
}
//解構函式
~DenseGraph(){}
//返回圖中節點的個數
int getV(){
return n;
}
//返回圖中邊的條數
int getE(){
return m;
}
//向圖中新增一條邊
void addEdga(int v, int w){
assert(v >= 0 && v < n);
assert(w >= 0 && w < n);
if(hasEdga(v, w)){
return;
}
g[v][w] = true;
//無向圖是雙向的
if(!directed){
g[w][v] = true;
}
m++;
}
//驗證圖中是否有v到w的邊
bool hasEdga(int v, int w){
assert(v >= 0 && v < n);
assert(w >= 0 && w < n);
return g[v][w];
}
//顯示圖中資訊
void show(){
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
cout<<g[i][j]<<"\t";
}
cout<<endl;
}
}
下面是稠密圖迭代器的部分:
// 鄰邊迭代器, 傳入一個圖和一個頂點,
// 迭代在這個圖中和這個頂點向連的所有頂點
class adjIterator{
private:
DenseGraph &G; //圖G的引用
int v; //傳入一個節點
int index; //對應的索引
public:
adjIterator(DenseGraph &graph, int v): G(graph){
assert(v >= 0 && v < G.n);
this->v = v;
// 索引從-1開始, 因為每次遍歷都需要呼叫一次next()
this->index = -1;
}
//解構函式
~adjIterator(){}
// 返回圖G中與頂點v相連線的第一個頂點
int begin(){
index = -1;
return next();
}
// 返回圖G中與頂點v相連線的下一個頂點
int next(){
for(index += 1; index <= G.getV(); index ++){
if( G.g[v][index] ){
return index;
}
return -1;
}
}
// 檢視是否已經迭代完了圖G中與頂點v相連線的所有頂點
bool end(){
return index >= G.getV();
}
};
};
- 稀疏圖的相鄰節點迭代器
同樣我們需要在稀疏圖這個類中編寫相應的迭代器
稀疏圖:
#include <iostream>
#include <vector>
#include <cassert>
using namespace std;
//稀疏圖—鄰接表
class SparseGraph{
private:
int n, m; //節點數和邊數
bool directed; //是否為無向圖
vector<vector<int>> g; //圖的具體資料
public:
SparseGraph(int n,bool directed){
assert(n >= 0);
this->n = n;
this->directed = directed;
// g初始化為n個空的vector, 表示每一個g[i]都為空, 即沒有任和邊
g = vector<vector<int>>(n, vector<int>());
}
//解構函式
~SparseGraph(){}
int getV(){
return n;
}
int getE(){
return m;
}
// 向圖中新增一個邊
void addEdga(int v, int w){
assert( v >= 0 && v < n );
assert( w >= 0 && w < n );
//將w放入g[v][i]中,將w與v相連
g[v].push_back(w);
if(v != w && !directed){
g[w].push_back(v);
}
m ++;
}
// 驗證圖中是否有從v到w的邊
bool hasEdga(int v, int w){
assert( v >= 0 && v < n );
assert( w >= 0 && w < n );
for(int i = 0; i <= g[v].size(); i++){
if(g[v][i] == w)
return true;
return false; }
}
//顯示圖中資訊
void show(){
for(int i = 0; i < n; i++){
cout<<"vector"<<":\t";
for(int j = 0; j < g[i].size(); j++){
cout<<g[i][j]<<":\t";
}
cout<<endl;
}
}
下面是迭代器部分:
// 鄰邊迭代器, 傳入一個圖和一個頂點,
// 迭代在這個圖中和這個頂點向連的所有頂點
class adjIterator{
private:
SparseGraph &G; //圖的引用
int v; //傳入節點
int index; //對應索引
public:
adjIterator(SparseGraph &graph, int v):G(graph){
this->v = v;
this->index = 0;
}
//解構函式
~adjIterator(){}
// 返回圖G中與頂點v相連線的第一個頂點
int begin(){
index = 0;
if( G.g[v].size() ){
return G.g[v][index];
}
return -1;
}
// 返回圖G中與頂點v相連線的下一個頂點
int next(){
index++;
if( index < G.g[v].size() )
return G.g[v][index];
}
bool end(){
return index >= G.g[v].size();
}
};
};
本作品採用《CC 協議》,轉載必須註明作者和本文連結