采用邻接矩阵完成无向图的“建立、深度遍历、广度遍历”操作

合集下载

数据结构中图的建立与深度优先、广度优先遍历

数据结构中图的建立与深度优先、广度优先遍历

数据结构中图的建立与深度优先、广度优先遍历《数据结构》实验报告实验内容:图的建立(邻接矩阵)及其深度优先、广度优先遍历学号:姓名:一、上机实验的问题和要求(需求分析):[ 题目]二、程序设计的基本思想,原理和算法描述:设计一个程序,建立图的邻接矩阵,并且进行图的广度优先遍历。

三、调试和运行程序过程中产生的问题及采取的措施:(略)四、源程序及注释[ 源程序] 程序名:9.cpp#include"stdio.h"#include"stdlib.h"#define INFINITY 100#define MAX_VERTEX_NUM 20#define MAX 100#define OK 1#define ERROR 0#define NULL 0typedef int VRType;typedef int VertextType;typedef int Status;typedef enum {DG,DN,UDG,UDN}GraphKind;typedef struct ArcCell{VRType adj;}ArcCell,AdjMatrix[MAX_VERTEX_NUM ][MAX_VERTEX_NUM ]; typedef struct{int vexs[MAX_VERTEX_NUM ];int arcs[4][4] ;int vexnum,arcnum;GraphKind Kind;}MGraph;int LocateVex(MGraph G,int v1){ int i;for(i=0;i<g.vexnum;i++)< p="">if(G.vexs[i]==v1)printf("%d\n",i);return i;}Status CreateUDN(MGraph &G){ int v1,v2;int i,j,k,w;printf("输入图的顶点数和弧数:");scanf("%d,%d",&G.vexnum,&G.arcnum); printf("输入顶点:");for(i=0;i<g.vexnum;i++)< p="">scanf("%d",&G.vexs[i]);for(i=0;i<g.vexnum;i++)< p="">for(j=0;j<g.vexnum;j++)< p="">G.arcs[i][j]=INFINITY ;printf("输入顶点关系:");for(k=0;k<g.arcnum;k++)< p="">{scanf("%d%d%d",&v1,&v2,&w);i=LocateVex(G,v1);j=LocateVex(G,v2);G.arcs[i][j]=w;G.arcs[j][i]=G.arcs[i][j];printf("%d\n%d\n",G.arcs[i][j],G.arcs[j][i]);}printf("图的邻接矩阵图是:\n");for(i=0;i<g.vexnum;i++)< p="">{for(j=0;j<g.vexnum;j++)< p="">printf("%d",G.arcs[i][j]);printf("\n");}return OK;}Status Visit(int e){//输出函数printf("%d\n",e);return OK;}//PrintElement//Status(*VisitFunc)(char v);int visited[MAX];void DFS(MGraph G,int v){ int j;Visit (v);visited[v]=1;for(j=1;j<g.vexnum;j++)< p="">if(!visited[j]&&G.arcs[v][j]!=INFINITY)DFS(G,j); } void DFSTraverse(MGraph G){ int v;for(v=0;v<g.vexnum;++v)< p="">visited[v]=0;for(v=0;v<g.vexnum;++v)< p="">if(!visited[v])DFS(G,v);/* 有关队列的操作*/#define MAX SIZE 100#define QElemType int#define OVERFLOW 0typedef struct{QElemType *base;int front;int rear;}SqQueue;Status InitQueue(SqQueue &Q){ Q.base=(QElemType*)malloc(MAXSIZE* sizeof(QElemType)); if(!Q.base)exit(OVERFLOW);Q.front=Q.rear=0;return 0;}Status EnQueue(SqQueue &Q,QElemType e){if(Q.rear+1==Q.front)return ERROR;Q.base[Q.rear]=e;Q.rear=Q.rear+1;return OK;}Status DeQueue(SqQueue &Q,QElemType &e){if(Q.front==Q.rear)return ERROR;e=Q.base[Q.front];Q.front=Q.front+1;return OK;}Status QueueEmpty(SqQueue Q){if(Q.front==Q.rear)return OK;else return ERROR;void BFSTraverse(MGraph &G){ int v,u,j;SqQueue Q;for(v=0;v<g.vexnum;v++)< p=""> visited[v]=0;InitQueue(Q);for(v=0;v<g.vexnum;++v)< p="">if(!visited[v]){visited[v]=1;Visit(v);EnQueue(Q,v);while(!QueueEmpty(Q)){ DeQueue(Q,u);for(j=1;j<g.vexnum;j++)< p="">if(!visited[j]&&G.arcs[v][j]!=INFINITY) { visited[j]=1;Visit(j);EnQueue(Q,j);}} }}void main(){ MGraph G;CreateUDN(G);printf("建图成功!");printf("深度优先遍历的结果:\n"); DFSTraverse(G);printf("广度优先遍历的结果:\n"); BFSTraverse(G);}五、运行结果运行结果:上一页下一页</g.vexnum;j++)<></g.vexnum;++v)<></g.vexnum;v++)<></g.vexnum;++v)<> </g.vexnum;++v)<> </g.vexnum;j++)<> </g.vexnum;j++)<> </g.vexnum;i++)<> </g.arcnum;k++)<> </g.vexnum;j++)<> </g.vexnum;i++)<> </g.vexnum;i++)<> </g.vexnum;i++)<>。

图的深度优先遍历和广度优先遍历

图的深度优先遍历和广度优先遍历

华北水利水电学院数据结构实验报告20 10 ~20 11 学年第一学期2008级计算机专业班级:107学号:200810702姓名:王文波实验四图的应用一、实验目的:1.掌握图的存储结构及其构造方法2.掌握图的两种遍历算法及其执行过程二、实验内容:以邻接矩阵或邻接表为存储结构,以用户指定的顶点为起始点,实现无向连通图的深度优先及广度优先搜索遍历,并输出遍历的结点序列。

提示:首先,根据用户输入的顶点总数和边数,构造无向图,然后以用户输入的顶点为起始点,进行深度优先和广度优先遍历,并输出遍历的结果。

三、实验要求:1.各班学号为单号的同学采用邻接矩阵实现,学号为双号的同学采用邻接表实现。

2.C/ C++完成算法设计和程序设计并上机调试通过。

3.撰写实验报告,提供实验结果和数据。

4.写出算法设计小结和心得。

四、程序源代码:#include<iostream.h>#define MaxVerNum 50struct edgenode{int endver;int inform;edgenode* edgenext;};struct vexnode{char vertex;edgenode* edgelink;};struct Graph{vexnode adjlists[MaxVerNum];int vexnum;int arcnum;};//队列的定义及相关函数的实现struct QueueNode{int nData;QueueNode* next;};struct QueueList{QueueNode* front;QueueNode* rear;};void EnQueue(QueueList* Q,int e) {QueueNode *q=new QueueNode;q->nData=e;q->next=NULL;if(Q==NULL)return;if(Q->rear==NULL)Q->front=Q->rear=q;else{Q->rear->next=q;Q->rear=Q->rear->next;}}void DeQueue(QueueList* Q,int* e) {if (Q==NULL)return;if (Q->front==Q->rear){*e=Q->front->nData;Q->front=Q->rear=NULL;}else{*e=Q->front->nData;Q->front=Q->front->next;}}//创建图void CreatAdjList(Graph* G){int i,j,k;edgenode* p1;edgenode* p2;cout<<"请输入顶点数和边数:"<<endl;cin>>G->vexnum>>G->arcnum;cout<<"开始输入顶点表:"<<endl;for (i=0;i<G->vexnum;i++){cin>>G->adjlists[i].vertex;G->adjlists[i].edgelink=NULL;}cout<<"开始输入边表信息:"<<endl;for (k=0;k<G->arcnum;k++){cout<<"请输入边<Vi,Vj>对应的顶点:";cin>>i>>j;p1=new edgenode;p1->endver=j;p1->edgenext=G->adjlists[i].edgelink;G->adjlists[i].edgelink=p1;p2=new edgenode;p2->endver=i;p2->edgenext=G->adjlists[j].edgelink;G->adjlists[j].edgelink=p2;//因为是无向图,所以有两次建立边表的过程}}//-------------------------------------------------------------深度优先遍历void DFS(Graph *G,int i,int visit[]){cout<<G->adjlists[i].vertex<<" ";visit[i]=1;edgenode *p=new edgenode;p=G->adjlists[i].edgelink;if(G->adjlists[i].edgelink&&!visit[p->endver]){DFS(G,p->endver,visit);}}void DFStraversal(Graph *G,char c)//深度优先遍历{cout<<"该图的深度优先遍历结果为:"<<endl;int visit[MaxVerNum];for(int i=0;i<G->vexnum;i++){visit[i]=0;//全部初始化为0,即未访问状态}int m;for (i=0;i<G->vexnum;i++){if (G->adjlists[i].vertex==c)//根据字符查找序号{m=i;DFS(G,i,visit);break;}}//继续访问未被访问的结点for(i=0;i<G->vexnum;i++){if(visit[i]==0)DFS(G,i,visit);}cout<<endl;}//-------------------------------------------------------------广度优先遍历void BFS(Graph* G,int v,int visit[]){QueueList *Q=new QueueList;Q->front=Q->rear=NULL;EnQueue(Q,v);while(Q->rear!=NULL){int e=0;DeQueue(Q,&e);cout<<G->adjlists[e].vertex<<" ";visit[e]=1;edgenode* p=new edgenode;p=G->adjlists[e].edgelink;if(p){int m=p->endver;if(m==0){EnQueue(Q,m);while(visit[m]==0){p=p->edgenext;if(p==NULL)break;m=p->endver;EnQueue(Q,m);}}}}}void BFStraversal(Graph *G,char c){cout<<"该图的广度优先遍历结果为:"<<endl;int visited[MaxVerNum];for (int i=0;i<G->vexnum;i++){visited[i]=0;}int m;for (i=0;i<G->vexnum;i++){if (G->adjlists[i].vertex==c){m=i;BFS(G,i,visited);break;}}//继续访问未被访问的结点for(i=0;i<G->vexnum;i++){if(visited[i]==0)BFS(G,i,visited);}cout<<endl;}void main(){Graph * G=new Graph;CreatAdjList(G);char ch;cout<<"请输入开始遍历的顶点:";cin>>ch;DFStraversal(G,ch);BFStraversal(G,ch);}五、程序运行情况(写出输入数据及运行结果)六、小结(包括收获、心得体会、存在的问题及解决问题的方法、建议等)注:内容一律使用宋体五号字,单倍行间距本次试验采用的是邻接表的方式实现图的深度优先遍历和广度优先遍历。

无向图深度遍历邻接矩阵报告

无向图深度遍历邻接矩阵报告
54.j=LocateVertex(G,v2);
55.G->arcs[i][j].adj=1;
56.G->arcs[j][i].adj=1;
57.}
58.return(OK);
59.}
60.
61.
62.void DepthFirstSearch(AdjMatrix G,int v)
63.{int j;
输出邻接矩阵0 1
1 0
实际结果:
第二组测试:
输入数据:顶点:0,1,2,3,4
预测结果:输出结点数据:0,1,2,3,4
输出邻接矩阵01 1 1 0
1 0 0 1 0
1 0 0 1 1
1 1 1 0 1
0 0 1 1 0
实际结果:
第三组测试:
输入数据:顶点:0,1,2,3,4 5 6
预测结果:输出结点数据:0123456
70.}
71.void TraverseGraph(AdjMatrix G)
72.{int i;
73.for(i=0;i<G.vexnum;i++) visited[i]=FALSE;
74.for(i=0;i<G.vexnum;i++)
75.if(!visited[i]) DepthFirstSearch(G,i);
typedef struct
{
VertexData vertex[MAX_VERTEX_NUM];//为顶点的集合
ArcNode arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
int vexnum,arcnum;//vexnum为顶点数,arcnum为弧数

邻接矩阵图的深度广度遍历

邻接矩阵图的深度广度遍历
{
for(int i=0;i&lt;G.vexnum;i++)
if(G.arcs[k][i]!=INFINITY)
return i;
}
return aph G,int i,int j) //图G中顶点i的第j个邻接顶点的下一个邻接顶点
{
{
cout&lt;&lt;&quot;边%d:&quot;,i;
scanf(&quot;%c-%c %d&quot;,&amp;a,&amp;b,&amp;w); //输入边和权值
temp=getchar(); //接收回车
Queue Q; //辅助队列Q
Q.InitQueue();
for(int i=0;i&lt;G.vexnum;i++)
if(!visited[i]) //i尚未访问
{
e=base[front];
front=(front+1)%QUEUE_SIZE;
}
public:
int *base;
int front;
int rear;
};
int Locate(Graph G,char c) //图G中查找元素c的位置
for(j=0;j&lt;G.vexnum;j++)
G.arcs[i][j]=INFINITY;
cout&lt;&lt;&quot;输入%d条边分别为:\n&quot;,G.arcnum; //读取边信息并初始化集合
for(i=0;i&lt;G.arcnum;i++) //初始化边

深度遍历和广度遍历例题

深度遍历和广度遍历例题

深度遍历和广度遍历例题深度遍历(Depth-First Search,DFS)和广度遍历(Breadth-First Search,BFS)是图遍历算法中常用的两种方法。

下面我将为你提供一个例题,并从多个角度进行全面的回答。

例题,给定一个无向图,使用深度遍历和广度遍历两种方法遍历该图,并输出遍历的结果。

首先,我们需要明确一下图的表示方式。

常用的图表示方法有邻接矩阵和邻接表,这里我们选择使用邻接表表示图。

假设我们有如下无向图:A./ \。

B---C.\ /。

D.邻接表表示如下:A: B, C.B: A, C, D.C: A, B, D.D: B, C.接下来,我们来进行深度遍历。

深度遍历的基本思想是从起始节点开始,尽可能深地访问每个节点,直到无法继续深入为止,然后回溯到上一个节点,继续访问其他未访问的节点。

从节点A开始进行深度遍历,访问顺序为A-B-C-D。

具体步骤如下:1. 将节点A标记为已访问。

2. 访问与节点A相邻的未被访问的节点,即节点B和节点C。

3. 选择其中一个节点(这里选择节点B),将其标记为已访问,并继续深度遍历该节点。

4. 对节点B进行相同的操作,访问与节点B相邻的未被访问的节点,即节点A、节点C和节点D。

5. 选择其中一个节点(这里选择节点C),将其标记为已访问,并继续深度遍历该节点。

6. 对节点C进行相同的操作,访问与节点C相邻的未被访问的节点,即节点A、节点B和节点D。

7. 选择其中一个节点(这里选择节点D),将其标记为已访问,并继续深度遍历该节点。

8. 由于节点D没有未被访问的相邻节点,回溯到节点C。

9. 由于节点C也没有未被访问的相邻节点,回溯到节点B。

10. 由于节点B还有一个未被访问的相邻节点(节点A),将其标记为已访问,并继续深度遍历该节点。

11. 由于节点A没有未被访问的相邻节点,回溯到节点B。

12. 由于节点B没有未被访问的相邻节点,回溯到节点A。

13. 完成深度遍历。

采用邻接矩阵表示法创建图,并进行深度优先搜索遍历

采用邻接矩阵表示法创建图,并进行深度优先搜索遍历

东华理工大学长江学院信息工程系数据结构课题设计专业:计算机科学与技术姓名:赵进城学号:20173031308 日期:2018/05/24采用邻接矩阵表示法创建图,并进行深度优先搜索遍历1、代码运行截图2、附源代码:// data.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <iostream>using namespace std;#define MVNum 100//最大顶点数typedef char VerTexType;//假设顶点的数据类型为字符型typedef int ArcType; //假设边的权值类型为整型//------------图的邻接矩阵------------------typedef struct{VerTexType vexs[MVNum]; //顶点表ArcType arcs[MVNum][MVNum]; //邻接矩阵int vexnum,arcnum; //图的当前点数和边数}Graph;bool visited[MVNum]; //访问标志数组,其初值为"false"int FirstAdjVex(Graph G , int v);//返回v的第一个邻接点int NextAdjVex(Graph G , int v , int w);//返回v相对于w的下一个邻接点int LocateVex(Graph G , VerTexType v){//确定点v在G中的位置for(int i = 0; i <G.vexnum; ++i)if(G.vexs[i] == v)return i;return -1;}//LocateVexvoid CreateUDN(Graph&G){//采用邻接矩阵表示法,创建无向网Gint i , j , k;cout<<"请输入总顶点数,总边数,以空格隔开:";cin>>G.vexnum>>G.arcnum;//输入总顶点数,总边数cout<<endl;cout<< "输入点的名称,如a" <<endl;for(i = 0; i <G.vexnum; ++i){cout<< "请输入第" << (i+1) << "个点的名称:";cin>>G.vexs[i]; //依次输入点的信息}cout<<endl;for(i = 0; i <G.vexnum; ++i) //初始化邻接矩阵,边的权值均置为极大值MaxIntfor(j = 0; j <G.vexnum; ++j)G.arcs[i][j] = 0;cout<< "输入边依附的顶点,如a b" <<endl;for(k = 0; k <G.arcnum;++k){//构造邻接矩阵VerTexType v1 , v2;cout<< "请输入第" << (k + 1) << "条边依附的顶点:";cin>> v1 >> v2;//输入一条边依附的顶点及权值i = LocateVex(G, v1); j = LocateVex(G, v2);//确定v1和v2在G中数组的下标G.arcs[j][i] = G.arcs[i][j] = 1;//置<v1, v2>的对称边<v2, v1>的权值为w}//for}//CreateUDNvoid DFS(Graph G, int v){//图G为邻接矩阵类型int w;cout<<G.vexs[v]<<" ";visited[v]=true;for (w=0;w<G.vexnum;w++)if((G.arcs[v][w]!=0)&&(!visited[w]))DFS(G,w);}//DFSint FirstAdjVex(Graph G , int v){//返回v的第一个邻接点int i;for(i = 0 ; i <G.vexnum ; ++i){if(G.arcs[v][i] == 1 && visited[i] == false) return i;}return -1;}//FirstAdjVexint NextAdjVex(Graph G , int v , int w){//返回v相对于w的下一个邻接点int i;for(i = w ; i <G.vexnum ; ++i){if(G.arcs[v][i] == 1 && visited[i] == false)return i;}return -1;}//NextAdjVexint main(){cout<< "******采用邻接矩阵表示图的深度优先搜索遍历********" <<endl<<endl;Graph G;CreateUDN(G);cout<<endl;cout<< "无向图G创建完成!" <<endl<<endl;cout<< "请输入遍历无向图G的起始点:"; VerTexType c;cin>> c;int i;for(i = 0 ; i <G.vexnum ; ++i){if(c == G.vexs[i])break;}cout<<endl;while(i >= G.vexnum){cout<< "该点不存在,请重新输入!" <<endl;cout<< "请输入遍历连通图的起始点:";cin>> c;for(i = 0 ; i <G.vexnum ; ++i){if(c == G.vexs[i])break;}}cout<< "深度优先搜索遍历无向图G结果:" <<endl;DFS(G , i);cout<<endl;return 0;}//main。

数据结构(visualc++)用邻接矩阵表示给定无向图并进行深度遍历

数据结构(visualc++)用邻接矩阵表示给定无向图并进行深度遍历

1.给定无向图,请用邻接矩阵表示法表示该图#include<iostream>#include<string>using namespace std;#define MAX 20typedef int Adj[MAX][MAX];typedef struct{string vexs[MAX]; //顶点表Adj arcs; //邻接矩阵int vexnum,arcnum; //图的顶点和弧数}MGraph;int LocateVex(MGraph &G,string u);int CreateUDN(MGraph &G){int i,k,j;string v1,v2;cout<<"请输入顶点数、弧数:";cin>>G.vexnum>>G.arcnum;cout<<"输入顶点:";for(i=0;i<G.vexnum;i++){cin>>G.vexs[i]; //构造顶点数}for(i=0;i<G.vexnum;i++){ //构造邻接矩阵for(j=0;j<G.vexnum;j++){G.arcs[i][j]=0;}}for(k=0;k<G.arcnum;k++){cout<<"输入第"<<k+1<<"边依附的两个顶点:";cin>>v1>>v2;i=LocateVex(G,v1); j=LocateVex(G,v2);G.arcs[i][j]=1;G.arcs[j][i]=1; //置<v1,v2>的对称弧<v2,v1>}return 0;v 4 v 5 v 3v 2 v 1}int LocateVex(MGraph &G,string u){ //确定u在G中序号int i;for (i=0;i<G.vexnum;i++){if (u==G.vexs[i])return i;}if (i==G.vexnum){cout<<"Error u!"<<endl;exit(1);}return 0;}void ShowG(MGraph &G){int i,j;for(i=0;i<G.vexnum;i++){cout<<G.vexs[i]<<" ";}cout<<endl;for(i=0;i<G.vexnum;i++){for(j=0;j<G.vexnum;j++){cout<<G.arcs[i][j]<<" ";}cout<<endl;}}main(){MGraph A;int a;a=CreateUDN(A);ShowG(A);}2.分别使用邻接矩阵表示法和邻接表表示法,用深度优先搜索法遍历该图。

基于邻接矩阵存储的图的深度优先遍历和广度优先遍历

基于邻接矩阵存储的图的深度优先遍历和广度优先遍历

基于邻接矩阵存储的图的深度优先遍历和⼴度优先遍历图的存储结构相⽐较线性表与树来说就复杂很多,对于线性表来说,是⼀对⼀的关系,所以⽤数组或者链表均可简单存放。

树结构是⼀对多的关系,所以我们要将数组和链表的特性结合在⼀起才能更好的存放。

那么我们的图,是多对多的情况,另外图上的任何⼀个顶点都可以被看作是第⼀个顶点,任⼀顶点的邻接点之间也不存在次序关系。

仔细观察以下⼏张图,然后深刻领悟⼀下:因为任意两个顶点之间都可能存在联系,因此⽆法以数据元素在内存中的物理位置来表⽰元素之间的关系(内存物理位置是线性的,图的元素关系是平⾯的)。

如果⽤多重链表来描述倒是可以做到,但在⼏节课前的树章节我们已经讨论过,纯粹⽤多重链表导致的浪费是⽆法想像的(如果各个顶点的度数相差太⼤,就会造成巨⼤的浪费)。

邻接矩阵(⽆向图)考虑到图是由顶点和边或弧两部分组成,合在⼀起⽐较困难,那就很⾃然地考虑到分为两个结构来分别存储。

顶点因为不区分⼤⼩、主次,所以⽤⼀个⼀维数组来存储是狠不错的选择。

⽽边或弧由于是顶点与顶点之间的关系,⼀维数组肯定就搞不定了,那我们不妨考虑⽤⼀个⼆维数组来存储。

图的邻接矩阵(Adjacency Matrix)存储⽅式是⽤两个数组来表⽰图。

⼀个⼀维数组存储图中顶点信息,⼀个⼆维数组(称为邻接矩阵)存储图中的边或弧的信息。

我们可以设置两个数组,顶点数组为vertex[4]={V0,V1,V2,V3},边数组arc[4][4]为对称矩阵(0表⽰不存在顶点间的边,1表⽰顶点间存在边)。

对称矩阵:所谓对称矩阵就是n阶矩阵的元满⾜a[i][j]=a[j][i](0<=i,j<=n)。

即从矩阵的左上⾓到右下⾓的主对⾓线为轴,右上⾓的元与左下⾓相对应的元全都是相等的。

有了这个⼆维数组组成的对称矩阵,我们就可以很容易地知道图中的信息:1. 要判定任意两顶点是否有边⽆边就⾮常容易了;2. 要知道某个顶点的度,其实就是这个顶点Vi在邻接矩阵中第i⾏(或第i列)的元素之和;3. 求顶点Vi的所有邻接点就是将矩阵中第i⾏元素扫描⼀遍,arc[i][j]为1就是邻接点咯。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

/* 采用邻接矩阵完成无向图的“建立、深度遍历、广度遍历”操作 */#include "stdio.h"#include "string.h"#define TRUE 1#define FALSE 0#define OVERFLOW -2#define OK 1#define ERROR 0typedef int Status;#define INFINITY INT_MAX /*最大值“无穷”*/#define MAX_VERTEX_NUM 20 /*最大顶点个数*/typedef int Boolean;typedef char VertexType[20];typedef int VRType;/**************以下为队列的操作************//****队列的类型定义****/typedef int QElemType;typedef struct QNode{QElemType data;struct QNode *next;} QNode, *QueuePtr;typedef struct{QueuePtr front;QueuePtr rear;} LinkQueue;/****初始化队列****/Status InitQueue(LinkQueue *Q){ (*Q).front=(*Q).rear=(QueuePtr)malloc(sizeof(QNode));if (!(*Q).front) exit(OVERFLOW);(*Q).front->next=NULL;return OK; }/****判断队列是否为空****/Status QueueEmpty (LinkQueue Q){ if (Q.front==Q.rear)return TRUE;elsereturn FALSE; }/****入队列****/Status EnQueue(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 DeQueue(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; }/**************以下为图的操作************//*图的类型定义*/typedef struct ArcCell{ VRType adj; /*图中有1/0表示是否有边,网中表示边上的权值*/ /* InfoType *info; 与边相关的信息*/} ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];typedef struct{ VertexType vexs[MAX_VERTEX_NUM]; /*顶点向量*/AdjMatrix arcs; /*邻接矩阵*/int vexnum,arcnum; /*图中当前顶点数和边数*/} MGraph;/*建立无向图的邻接矩阵*/void CreateGraph(MGraph *G){ int i,j,k; VertexType v1,v2;printf("\nInput MG vexnum,arcnum:");scanf("%d,%d",&(*G).vexnum,&(*G).arcnum);printf("Input %d vexs:",(*G).vexnum);for(i=0;i<(*G).vexnum;i++) /*输入顶点向量*/ { scanf("%s",(*G).vexs[i]); }printf("vexs list\n");for(i=0;i<G->vexnum;i++) /*输出顶点向量*/puts(G->vexs[i]);for(i=0;i<(*G).vexnum;i++) /*邻接矩阵初始化*/ for(j=0;j<(*G).vexnum;j++)(*G).arcs[i][j].adj=0;printf("\nInput %d arcs(vi vj):\n",(*G).arcnum); for(k=0;k<(*G).arcnum;k++) /*输入无权图的边*/ { scanf("%s%s",v1,v2);i=LocateVex(*G,v1); j=LocateVex(*G,v2);(*G).arcs[i][j].adj=1;(*G).arcs[j][i]=(*G).arcs[i][j];}}/* 顶点在顶点向量中的定位*/int LocateVex(MGraph G,VertexType v){ int i;for(i=0;i<G.vexnum;i++)if (strcmp(v,G.vexs[i])==0) break;return i;}/* 查找第1个邻接点 */int FirstAdjVex(MGraph G,int v){ int j,p=-1;for(j=0;j<G.vexnum;j++)if (G.arcs[v][j].adj==1) {p=j; break;}return p;}/* 查找下一个邻接点 */int NextAdjVex(MGraph G,int v,int w){ int j,p=-1;for(j=w+1;j<G.vexnum;j++)if (G.arcs[v][j].adj==1) {p=j; break;}return p;}/*按邻接矩阵方式输出无向图*/void PrintGraph(MGraph G){ int i,j;printf("\nMGraph:\n");for(i=0; i<G.vexnum; i++){ printf("%10s",G.vexs[i]);for(j=0; j<G.vexnum; j++)printf("%4d",G.arcs[i][j].adj);printf("\n");}}/*深度遍历*/Boolean visited[MAX_VERTEX_NUM]; /* 设置全局的访问标志数组 */void Dfs(MGraph G, int v){ int w;visited[v]=TRUE;printf("%s",G.vexs[v]);for(w=FirstAdjVex(G,v); w>=0; w=NextAdjVex(G,v,w))if(!visited[w]) Dfs(G,w);}void DfsTraverse(MGraph G){ int v;for (v=0; v<G.vexnum; v++)visited[v]=FALSE;for(v=0; v<G.vexnum; v++)if (!visited[v]) Dfs(G,v);}/* 广度遍历 */void BfsTraverse(MGraph G){ int v,u,w; LinkQueue Q;for(v=0; v<G.vexnum; v++) visited[v]=FALSE;InitQueue(&Q);for(v=0; v<G.vexnum; v++)if (!visited[v]){ visited[v]=TRUE;printf("%s",G.vexs[v]);EnQueue(&Q,v);while(!QueueEmpty(Q)){ DeQueue(&Q,&u);for(w=FirstAdjVex(G,u); w>=0; w=NextAdjVex(G,u,w))if (!visited[w]){ visited[w]=TRUE;printf("%s",G.vexs[w]);EnQueue(&Q,w);}}}}/*主函数*/main(){ int w;MGraph G;CreateGraph(&G);PrintGraph(G);printf("\nDfs:"); DfsTraverse(G); /* 深度遍历 */ printf("\nBfs:"); BfsTraverse(G); /* 广度遍历 */ }。

相关文档
最新文档