鄰接表表示圖(有向、無向圖)及廣度、深度遍歷)
阿新 • • 發佈:2019-01-01
鄰接表表示圖
#include <iostream>
#include <malloc.h>
#include <queue>
using namespace std;
#define VertexType char
#define MaxVertexNum 20 //最大頂點數
queue<int>Q; //輔助佇列
enum GraphType{DG, UDG}; //DG表示有向圖,UDG表示無向圖
typedef struct ArcNode{ //邊結點
int adjvex; //鄰接點的下標
struct ArcNode *nextarc; //後繼鏈指標
}ArcNode;
typedef struct VNode{ //頂點結點
VertexType data; //頂點資料
ArcNode *firstarc; //邊鏈頭指標
}VNode, AdjList[MaxVertexNum];
typedef struct{
AdjList vertices; //鄰接表
int vexnum, arcnum; //頂點數和邊數
GraphType kind; //圖種類標誌
}ALGraph;
//建立有向圖
void CreateDGGraph(ALGraph &G)
{
int m, n; //邊<Vm,Vn>的下標
ArcNode *vm, *vn; //構成邊<Vm,Vn>的兩個頂點
cout << "請輸入頂點數和邊數:";
cin >> G.vexnum >> G.arcnum;
cout << "請輸入頂點的資訊:" << endl;
//獲取頂點資訊
for(int i=0; i<G.vexnum; i++)
{
cin >> G.vertices[i].data;
G.vertices[i].firstarc=NULL;
}
//建立鄰接表,採用頭插法
for(int i=0; i<G.arcnum; i++)
{
cout << "請輸入<Vi,Vj>的下標:";
cin >> m >> n;
vm=(ArcNode*)malloc(sizeof(ArcNode));
vm->adjvex=n;
vm->nextarc=NULL;
if(G.vertices[m].firstarc==NULL)
{
vn=G.vertices[m].firstarc=vm;
}
else
{
vn=vn->nextarc=vm;
}
}
}
//建立無向圖
void CreateUDGGraph(ALGraph &G)
{
int m, n; //邊<Vm,Vn>的下標
ArcNode *pe;
cout << "請輸入頂點數和邊數:";
cin >> G.vexnum >> G.arcnum;
cout << "請輸入頂點的資訊:" << endl;
//獲取頂點資訊
for(int i=0; i<G.vexnum; i++)
{
cin >> G.vertices[i].data;
G.vertices[i].firstarc=NULL;
}
//建立鄰接表,採用頭插法
for(int i=0; i<G.arcnum; i++)
{
cout << "請輸入<Vi,Vj>的下標:";
cin >> m >> n;
pe=(ArcNode*)malloc(sizeof(ArcNode));
pe->adjvex=n;
pe->nextarc=G.vertices[m].firstarc;
G.vertices[m].firstarc=pe;
pe=(ArcNode*)malloc(sizeof(ArcNode));
pe->adjvex=m;
pe->nextarc=G.vertices[n].firstarc;
G.vertices[n].firstarc=pe;
}
}
void PrintALGraph(ALGraph &G)
{
ArcNode *p;
for (int i=0;i<G.vexnum;i++)
{
cout << "頂點" << i << "(" << G.vertices[i].data << ") "": ";
for (p=G.vertices[i].firstarc; p!=NULL;p=p->nextarc)
cout << p->adjvex << "(" << G.vertices[p->adjvex].data << ") ";
if (p==NULL)
cout << endl;
}
}
//求圖中頂點v的第一個鄰接點,若有則返回頂點下標。若v沒有鄰接點或圖中不存在v,則返回-1
int FirstNeighbor(ALGraph G, int v)
{
ArcNode *next=G.vertices[v].firstarc;
if(next)
{
return next->adjvex;
}
return -1;
}
//返回除頂點v外的下一個頂點w
int NextNeighbor(ALGraph G, int v, int w)
{
ArcNode *next=G.vertices[v].firstarc;
while(next)
{
if(next->adjvex==w)break;
next=next->nextarc;
}
if(next)
{
ArcNode *nextNode=next->nextarc;
if(nextNode)
{
return nextNode->adjvex;
}
}
return -1;
}
void visit(ALGraph G, int v)
{
cout << G.vertices[v].data << " ";
}
bool visited[MaxVertexNum]; //訪問標記陣列
//從頂點v出發,採用遞迴,廣度遍歷圖G
void BFS(ALGraph G, int v)
{
visit(G, v);
visited[v]=true; //設已訪問標記
Q.push(v); //頂點v入隊
while(!Q.empty())
{
v=Q.front();
Q.pop();
for(int w=FirstNeighbor(G, v); w>=0; w=NextNeighbor(G, v, w))
{ //檢查v所以鄰接點
if(!visited[w]) //w為v的尚未訪問的鄰接頂點
{
visit(G, w);
visited[w]=true; //設已訪問標記
Q.push(w); //頂點w入隊
}
}
}
}
//從頂點出發,進行廣度優先遍歷
void BFSTraverse(ALGraph G)
{
for(int i=0; i<G.vexnum; i++)
{
visited[i]=false; //訪問標記陣列初始化
}
for(int i=0; i<G.vexnum; i++) //從0號頂點開始遍歷
{
if(!visited[i])
{
BFS(G, i); //vi未訪問過,從vi開始BFS
}
}
}
//從頂點v出發,採用遞迴,深度遍歷圖G
void DFS(ALGraph G, int v)
{
visit(G, v); //訪問v
visited[v]=true; //設已訪問標記
for(int w=FirstNeighbor(G, v); w>=0; w=NextNeighbor(G, v, w))
{ //w為v的尚未訪問的鄰接頂點
if(!visited[w])
{
DFS(G, w);
}
}
}
//從頂點出發,進行深度優先遍歷
void DFSTraverse(ALGraph G)
{
for(int i=0; i<G.vexnum; i++)
{
visited[i]=false; //訪問標記陣列初始化
}
for(int i=0; i<G.vexnum; i++) //從0號頂點開始遍歷
{
if(!visited[i])
{
DFS(G, i); //vi未訪問過,從vi開始DFS
}
}
}
int main()
{
ALGraph G;
//CreateALGraph(G);
int tag; //有向無向圖標誌
cout << "請輸入1(有向圖),2(無向圖):";
cin >> tag;
if(tag==1)
{
G.kind=DG;
CreateDGGraph(G); //建立有向圖
}
else
{
G.kind=UDG;
CreateUDGGraph(G); //建立無向圖
}
cout << "===========================" << endl;
PrintALGraph(G);
cout <<endl;
cout << "廣度遍歷:";
BFSTraverse(G);
cout << endl;
cout << "深度遍歷:";
DFSTraverse(G);
return 0;
}