http://www.cnblogs.com/dolphin0520/archive/2011/07/13/2105236.html
遞歸 非遞歸(用棧)
圖的遍歷有兩種遍歷方式:深度優先遍歷(depth-first search)和廣度優先遍歷(breadth-first search)。
1.深度優先遍歷
基本思想:首先從圖中某個頂點v0出發,訪問此頂點,然後依次從v0相鄰的頂點出發深度優先遍歷,直至圖中所有與v0路徑相通的頂點都被訪問了;若此時尚有頂點未被訪問,則從中選一個頂點作爲起始點,重複上述過程,直到所有的頂點都被訪問。可以看出深度優先遍歷是一個遞歸的過程。
如下圖中的一個無向圖
其深度優先遍歷得到的序列爲:
0->1->3->7->4->2->5->6
2.廣度優先遍歷
基本思想:首先,從圖的某個頂點v0出發,訪問了v0之後,依次訪問與v0相鄰的未被訪問的頂點,然後分別從這些頂點出發,廣度優先遍歷,直至所有的頂點都被訪問完。
如上面圖中
其廣度優先遍歷得到的序列爲:
0->1->2->3->4->5->6->7
#include<iostream>
#include<queue>
#include<stack>
#include<stdlib.h>
#define MAX 100
using namespace std;
typedef struct
{
int edges[MAX][MAX]; //鄰接矩陣
int n; //頂點數
int e; //邊數
}MGraph;
bool visited[MAX]; //標記頂點是否被訪問過
void creatMGraph(MGraph &G) //用引用作參數
{
int i,j;
int s,t; //存儲頂點編號
int v; //存儲邊的權值
for(i=0;i<G.n;i++) //初始化
{
for(j=0;j<G.n;j++)
{
G.edges[i][j]=0;
}
visited[i]=false;
}
for(i=0;i<G.e;i++) //對矩陣相鄰的邊賦權值
{
scanf("%d %d %d",&s,&t,&v); //輸入邊的頂點編號以及權值
G.edges[s][t]=v;
}
}
void DFS(MGraph G,int v) //深度優先搜索
{
int i;
printf("%d ",v); //訪問結點v
visited[v]=true;
for(i=0;i<G.n;i++) //訪問與v相鄰的未被訪問過的結點
{
if(G.edges[v][i]!=0&&visited[i]==false)
{
DFS(G,i);
}
}
}
void DFS1(MGraph G,int v) //非遞歸實現
{
stack<int> s;
printf("%d ",v); //訪問初始結點
visited[v]=true;
s.push(v); //入棧
while(!s.empty())
{
int i,j;
i=s.top(); //取棧頂頂點
for(j=0;j<G.n;j++) //訪問與頂點i相鄰的頂點
{
if(G.edges[i][j]!=0&&visited[j]==false)
{
printf("%d ",j); //訪問
visited[j]=true;
s.push(j); //訪問完後入棧
break; //找到一個相鄰未訪問的頂點,訪問之後則跳出循環
}
}
if(j==G.n) //如果與i相鄰的頂點都被訪問過,則將頂點i出棧
s.pop();
}
}
void BFS(MGraph G,int v) //廣度優先搜索
{
queue<int> Q; //STL模板中的queue
printf("%d ",v);
visited[v]=true;
Q.push(v);
while(!Q.empty())
{
int i,j;
i=Q.front(); //取隊首頂點
Q.pop();
for(j=0;j<G.n;j++) //廣度遍歷
{
if(G.edges[i][j]!=0&&visited[j]==false)
{
printf("%d ",j);
visited[j]=true;
Q.push(j);
}
}
}
}
int main(void)
{
int n,e; //建立的圖的頂點數和邊數
while(scanf("%d %d",&n,&e)==2&&n>0)
{
MGraph G;
G.n=n;
G.e=e;
creatMGraph(G);
DFS(G,0);
printf("\n");
// DFS1(G,0);
// printf("\n");
// BFS(G,0);
// printf("\n");
}
return 0;
}