图的构造和两种遍历(DFS和BFS)
图的构造函数
Status LocateVex(MGraph G,VertexType u)//访问无向网图中该顶点所在位置
{
int i;
for(i=1;i<=G.vexnum;++i)
if(G.vexs[i]==u)
return i;
return 0;
}
void CreateUDN(MGraph &G)//创建无向网图
{
int i,j,k,w;
VertexType v1,v2;
char tmp;
cout<<"请输入顶点数,边数和信息(无信息则输入0)"<<endl;
cin>>G.vexnum>>G.arcnum>>G.IncInfo;
cout<<"请输入这"<<G.vexnum<<"个顶点编号:";
for(i=1;i<=G.vexnum;++i)
cin>>G.vexs[i];
for(i=1;i<=G.vexnum;++i)
{
for(j=1;j<=G.vexnum;++j)
G.arcs[i][j].adj=0;
}
cout<<"请输入这"<<G.arcnum<<"条边:";
for(k=1;k<=G.arcnum;++k)
{
cin>>v1>>v2;
i=LocateVex(G,v1);
j=LocateVex(G,v2);
G.arcs[i][j].adj=1;
if(G.IncInfo)
cin>>G.arcs[i][j].info;
G.arcs[j][i]=G.arcs[i][j];
}
}
int FirstAdjVex(MGraph G,VertexType v)//访问v后的第一个连通结点
{
int k,j,t;
k=LocateVex(G,v);
if(k)
{
t=INFINITY;
for(j=1;j<=G.vexnum;j++)
if(G.arcs[k][j].adj!=t)
return j;
}
return 0;
}
int NextAdjVex(MGraph G,VertexType v,VertexType w)//访问v后的相对于w的第一个连通结点
{
int k1,k2,j,t;
k1=LocateVex(G,v);
k2=LocateVex(G,w);
if(k1 && k2)
{
t=INFINITY;
for(j=k2+1;j<=G.vexnum;j++)
{
if(G.arcs[k1][j].adj!=t)
return j;
}
}
return 0;
}
void ShowMGraph(MGraph &G){//输出邻接矩阵
for(int i=1;i<=G.vexnum;++i){
for(int j=1;j<=G.vexnum;++j){
cout<<G.arcs[i][j].adj<<" ";
}
cout<<endl;
}
}
DFS(递归思想)
void DFS(MGraph G,int v)
{
int w;
visited[v]=TRUE;
VisitFunc(G.vexs[v]);
for(w=FirstAdjVex(G,G.vexs[v]);w;w=NextAdjVex(G,G.vexs[v],G.vexs[w]))
if(!visited[w])
DFS(G,w);
}
void DFSTraverse(MGraph G,void(Visit)(VertexType))
{
int v;
VisitFunc=Visit;
for(v=1;v<=G.vexnum;v++)//初始化
visited[v]=FALSE;
for(v=1;v<=G.vexnum;v++)
if(!visited[v])
DFS(G,v);
}
BFS(借助队列)
void BFSTraverse(MGraph G,void(Visit)(VertexType))
{
int v,w;
LinkQueue q;
QElemType e;
for(v=1;v<=G.vexnum;v++)//初始化
visited[v]=FALSE;
InitQueue(q);
for(v=1;v<=G.vexnum;v++)
{
if(!visited[v])
{
visited[v]=TRUE;
Visit(G.vexs[v]);
InsertQueue(q,v);
while(!EmptyQueue(q))
{
DeleteQueue(q,e);
for(w=FirstAdjVex(G,G.vexs[e]);w;w=NextAdjVex(G,G.vexs[e],G.vexs[w]))
{
if(!visited[w])
{
visited[w]=TRUE;
Visit(G.vexs[w]);
InsertQueue(q,w);
}
}
}
}
}
}
完整代码:
#include<bits/stdc++.h>
using namespace std;
#define MAX 101
#define INF 0x3f3f3f3f
#define Listsize 100
#define INFINITY INT_MAX
#define MAX_VERTEX_NUM 20
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef char InfoType;
typedef int VRType;
typedef char VertexType;
typedef int QElemType;
typedef struct QNode{
QElemType data;
struct QNode *next;
}QNode, *QueuePtr;
typedef struct{
QueuePtr front;
QueuePtr rear;
}LinkQueue;
typedef struct ArcCell{
VRType adj;
InfoType * info;
}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef struct{
VertexType vexs[MAX_VERTEX_NUM];
AdjMatrix arcs;
int vexnum,arcnum;
int IncInfo;
}MGraph;
MGraph G;
Status visited[MAX_VERTEX_NUM+1];
void (*VisitFunc)(VertexType e);
Status InitQueue(LinkQueue &q)
{
q.front=q.rear=(QueuePtr)malloc(sizeof(QNode));
if(!q.front )
exit(OVERFLOW);
q.front->next=NULL;
return OK;
}
Status DestroyQueue(LinkQueue &q){
while(q.front){
q.rear=q.front->next;
free(q.front);
q.front=q.rear;
}
return OK;
}
Status ClearQueue(LinkQueue &q)
{
QueuePtr p1,p2;
q.rear=q.front;
p1=q.front->next;
q.front->next=NULL;
while(p1)
{
p2=p1;
p1=p1->next;
free(p2);
}
return OK;
}
Status InsertQueue(LinkQueue &q,QElemType e){
QueuePtr p;
p=(QueuePtr)malloc(sizeof(QNode));
if(!p)
exit(OVERFLOW);
p->data=e;
p->next=NULL;
q.rear->next=p;
q.rear=p;
return OK;
}
Status DeleteQueue(LinkQueue &q,QElemType &e){
QueuePtr p;
if(q.front==q.rear)
return ERROR;
p=q.front->next;
e=p->data;
q.front->next=p->next;
if(q.rear==p)
q.rear=q.front;
free(p);
return OK;
}
Status EmptyQueue(LinkQueue &q)
{
if(q.front->next==NULL)
return 1;
else
return 0;
}
Status LengthQueue(LinkQueue &q)
{
int len=0;
QueuePtr p=q.front;
while(q.rear!=p)
{
len++;
p=p->next;
}
return len;
}
Status GetHead(LinkQueue q,QElemType &e)
{
QueuePtr p;
if(q.front==q.rear)
return ERROR;
p=q.front->next;
e=p->data;
return OK;
}
Status LocateVex(MGraph G,VertexType u)
{
int i;
for(i=1;i<=G.vexnum;++i)
if(G.vexs[i]==u)
return i;
return 0;
}
void CreateUDN(MGraph &G)
{
int i,j,k,w;
VertexType v1,v2;
char tmp;
cout<<"请输入顶点数,边数和信息(无信息则输入0)"<<endl;
cin>>G.vexnum>>G.arcnum>>G.IncInfo;
cout<<"请输入这"<<G.vexnum<<"个顶点编号:";
for(i=1;i<=G.vexnum;++i)
cin>>G.vexs[i];
for(i=1;i<=G.vexnum;++i)
{
for(j=1;j<=G.vexnum;++j)
G.arcs[i][j].adj=0;
}
cout<<"请输入这"<<G.arcnum<<"条边:";
for(k=1;k<=G.arcnum;++k)
{
cin>>v1>>v2;
i=LocateVex(G,v1);
j=LocateVex(G,v2);
G.arcs[i][j].adj=1;
if(G.IncInfo)
cin>>G.arcs[i][j].info;
G.arcs[j][i]=G.arcs[i][j];
}
}
int FirstAdjVex(MGraph G,VertexType v)
{
int k,j,t;
k=LocateVex(G,v);
if(k)
{
t=INFINITY;
for(j=1;j<=G.vexnum;j++)
if(G.arcs[k][j].adj!=t)
return j;
}
return 0;
}
int NextAdjVex(MGraph G,VertexType v,VertexType w)
{
int k1,k2,j,t;
k1=LocateVex(G,v);
k2=LocateVex(G,w);
if(k1 && k2)
{
t=INFINITY;
for(j=k2+1;j<=G.vexnum;j++)
{
if(G.arcs[k1][j].adj!=t)
return j;
}
}
return 0;
}
void ShowMGraph(MGraph &G){
for(int i=1;i<=G.vexnum;++i){
for(int j=1;j<=G.vexnum;++j){
cout<<G.arcs[i][j].adj<<" ";
}
cout<<endl;
}
}
void PrintElem(char c)
{
cout<<c<<' ';
}
void DFS(MGraph G,int v)
{
int w;
visited[v]=TRUE;
VisitFunc(G.vexs[v]);
for(w=FirstAdjVex(G,G.vexs[v]);w;w=NextAdjVex(G,G.vexs[v],G.vexs[w]))
if(!visited[w])
DFS(G,w);
}
void DFSTraverse(MGraph G,void(Visit)(VertexType))
{
int v;
VisitFunc=Visit;
for(v=1;v<=G.vexnum;v++)
visited[v]=FALSE;
for(v=1;v<=G.vexnum;v++)
if(!visited[v])
DFS(G,v);
}
void BFSTraverse(MGraph G,void(Visit)(VertexType))
{
int v,w;
LinkQueue q;
QElemType e;
for(v=1;v<=G.vexnum;v++)
visited[v]=FALSE;
InitQueue(q);
for(v=1;v<=G.vexnum;v++)
{
if(!visited[v])
{
visited[v]=TRUE;
Visit(G.vexs[v]);
InsertQueue(q,v);
while(!EmptyQueue(q))
{
DeleteQueue(q,e);
for(w=FirstAdjVex(G,G.vexs[e]);w;w=NextAdjVex(G,G.vexs[e],G.vexs[w]))
{
if(!visited[w])
{
visited[w]=TRUE;
Visit(G.vexs[w]);
InsertQueue(q,w);
}
}
}
}
}
}
void menu()
{
cout<<"***********************************"<<endl;
cout<<"************无向网图***************"<<endl;
cout<<"***********************************"<<endl;
cout<<"******** 1.构建网图 *******"<<endl;
cout<<"******** 2.输出邻接矩阵 *******"<<endl;
cout<<"******** 3.深度优先遍历 *******"<<endl;
cout<<"******** 4.广度优先遍历 *******"<<endl;
cout<<"******** 5.退出 *******"<<endl;
cout<<"***********************************"<<endl;
}
int main()
{
int v,e;
menu();
int order;
do
{
cout<<"请输入选择: " ;
cin>>order;
switch(order)
{
case 1:
v=0,e=0;
CreateUDN(G);
cout<<"创建成功"<<endl;
break;
case 2:
cout<<"邻接矩阵为:"<<endl;
ShowMGraph(G);
break;
case 3:
cout<<"深度优先遍历为:";
DFSTraverse(G,PrintElem);
cout<<endl;
break;
case 4:
cout<<"广度优先遍历为:";
BFSTraverse(G,PrintElem);
cout<<endl;
break;
case 5:
cout<<"程序已退出"<<endl;
break;
default:
cout<<"输入指令错误"<<endl;
break;
}
}while(order!=5);
return 0;
}
如图:
邻接矩阵为
0 1 0 0 0 1
1 0 1 1 0 0
0 1 0 1 1 0
0 1 1 0 1 0
0 0 1 1 0 1
1 0 0 0 1 0
并非最终版本,如有错误,请指出