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

引用文件xhdl.cpp:循环队列

#include<stdio.h>
#include<stdlib.h>
#define OVERFLOW 0
#define OK 1
#define ERROR 0
#define QelemType int
#define MAXQSIZE 100
#define Status int
typedef struct{
	QelemType *base;
	int front;
	int rear;
}SqQueue;
Status InitQueue(SqQueue &Q){
	Q.base=(QelemType*)malloc(MAXQSIZE*sizeof(QelemType));
	if(!Q.base)exit(OVERFLOW);
	Q.front=Q.rear=0;
	return OK;
}
Status EnQueue(SqQueue &Q,char e){
	if((Q.rear+1)%MAXQSIZE==Q.front)
	return ERROR;
	Q.base[Q.rear]=e;
	Q.rear=(Q.rear+1)%MAXQSIZE;
	return OK;
} 
Status DeQueue(SqQueue &Q,int &e){
	if(Q.front==Q.rear)
	return ERROR;
	e=Q.base[Q.front];
	Q.front=(Q.front+1)%MAXQSIZE;
	return OK;
}
Status QueueEmpty (SqQueue &Q)
{
	if(Q.rear+1%MAXQSIZE==Q.front)
	{
		return 1;
	}else{
		return 0;
	}
} 
#include<stdio.h>
#include<stdlib.h>
#include<limits.h>//含有INI_MAX=2的31次方-1
#include "xhdl.cpp"//调用外部文件 
#define INFINITY INT_MAX
#define MAX_VERTEX_NUM 20
#define Status int
#define ERROR 0
#define OK 1
#define VRType int
#define InfoType int
#define VertexType char
int visited[MAX_VERTEX_NUM];
typedef enum{DG,DN,UDG,UDN} GraphKind;//枚举类型,对应有向图、网,无向图、网
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;//图的当前顶点数和弧数
	GraphKind Kind;//图的种类标志
}MGraph;//图的所有信息 

int LocateVex(MGraph &G,char v)
{  for(int i=0;i<G.vexnum;i++)
          if(G.vexs[i]==v)
   return i;
}
Status CreateUDN(MGraph &G) //在邻接矩阵存储结构上,构造无向网G
{
	char v1,v2;
	int  w;
    printf("请输入无向图的顶点数和边数");
    scanf("%d%d",&G.vexnum,&G.arcnum);//读入顶点和边数目
	printf("请按顺序输入顶点信息");
	for(int i=0;i<G.vexnum;i++){
		fflush(stdin);
	   scanf("%c",&G.vexs[i]);//构造顶点向量,用来表示行坐标或者列坐标,因为临接矩阵是没有位置来存表头的
	   fflush(stdin);
	}
	printf("%c%c%c",G.vexs[0],G.vexs[1],G.vexs[2]);
	for(int i=0;i<G.vexnum;i++) //邻接矩阵初始化
	   for(int j=0;j<G.vexnum;j++)
	   {
		G.arcs[i][j]={0,NULL};
	   }
	for(int k=0;k<G.arcnum;k++)//构造邻接矩阵
	{
        printf("请依次输入每条边依附的顶点和权值");
        fflush(stdin);
	    scanf("%c %c %d",&v1,&v2,&w);
	    fflush(stdin);
		int i=LocateVex(G,v1);
		int j=LocateVex(G,v2);//确定v1、v2在图中的位置
		G.arcs[i][j].adj=w;//边<v1,v2>的权值
		G.arcs[j][i]=G.arcs[i][j];//置<v1,v2>的对称弧<v2,v1>
	}
	for(int i=0;i<G.vexnum;i++)
	{
		for(int j=0;j<G.vexnum;j++)
		{
			printf("%15d\t",G.arcs[i][j].adj);
		}
		printf("\n");
	}
		return OK;
}//CreateUDN

void DFS(MGraph G, int i)
{
    visited[i] = 1;
    printf("%c ", G.vexs[i]);
    for (int j=0; j<G.vexnum; ++j)
    {
        if (G.arcs[i][j].adj!=INFINITY && !visited[j])
            DFS(G, j);//递归,如果两者有关系且邻接点未被访问过就访问 
    }
}
void DFSTraverse(MGraph G)
{
    for (int i=0; i<G.vexnum; i++)//初始化,全未被访问过 
        visited[i] = 0;
    for (int i=0; i<G.vexnum; i++)// 
    {
        if (!visited[i])
            DFS(G, i);
    } 
}
//-------------------------------------------------
//-------------构造邻接表------------------ 
typedef struct ArcNode//定义表节点
{
	int adjvex;//该弧所指的顶点位置
	struct ArcNode *nextarc;//指向下一条弧的指针
	InfoType *info;//该弧相关信息的指针
}ArcNode;

typedef struct Vnode//定义头结点
{
	VertexType data;//顶点的信息
	ArcNode *firstarc;//指向第一条依附于该顶点的弧的指针
}VNode,AdjList[MAX_VERTEX_NUM];//头结点是个一维结构体数组

typedef struct//图的所有信息 
{
	AdjList vertices;//头结点的一维数组
	int vexnum,arcnum;//图的当前顶点数和弧数
	int kind;//图的种类
}ALGraph;

void CreatAlgraph(ALGraph &G)//创建以邻接表为存储结构的无向图
{
	  printf("请输入顶点和边的数目");
	  scanf("%d%d",&G.vexnum,&G.arcnum);//读入顶点的数目
      printf("请依次输入顶点的值");
      for(int i=0;i<G.vexnum;i++) //读入顶点值
      {
    	fflush(stdin); 
	   scanf("%c",&G.vertices[i].data);
	   fflush(stdin); 
	   G.vertices[i].firstarc=NULL;
	    }
       printf("请依次输入有关联的结点序号");
      for(int i=0;i<G.arcnum;i++)//建立边<s,d>(<d,s>)的信息
      {
			int s,d;
			ArcNode*p,*q;
			fflush(stdin);//清除上次循环遗留下的回车 
	        scanf("%d %d",&s,&d);//读入顶点序号
	        fflush(stdin);
            p=(ArcNode*)malloc(sizeof(ArcNode));//建立表节点
            q=(ArcNode*)malloc(sizeof(ArcNode));
            p->adjvex=d;//给弧所指的节点赋值
	        q->adjvex=s;
            p->nextarc=G.vertices[s].firstarc;G.vertices [s].firstarc=p;//这是一种逆向建立链表的方法
            q->nextarc=G.vertices[d].firstarc;G.vertices[d].firstarc=q;//<s,d>
    }
}

Status Print(int i,ALGraph G)
{
	printf("%c",G. vertices[i].data);
	return OK;
}
//------------邻接表的广度优先遍历-------------
void BFSTraverse( ALGraph G, Status ( * Visit) (int v,ALGraph))
{
	int v,u;
	ArcNode *w;
	Visit=Print;
     for(v=0;v<G.vexnum; ++v)
     visited[v] = 0;
	 SqQueue Q;
	 InitQueue(Q);     //初始化
     for (v=0;v<G.vexnum;++v)
          if ( ! visited[ v ] ) //v没有被访问
        {
		     visited[v] = 1;
			 Visit(v,G);
             EnQueue(Q,v);  //入队列
	         while (QueueEmpty (Q))
	        {
			     DeQueue(Q,u);
	             for (w= G.vertices[u].firstarc; w;w=w->nextarc)
             	 if( !visited[ w->adjvex ] )  //w为u的尚未访问的邻接顶点
	     	         {
					     visited[ w->adjvex ] = 1;
						    Visit(w->adjvex,G);
						 EnQueue(Q, w->adjvex);
			         }//if;
            } //while
        }//if
}//BFSTraverse 
//---------------------------------------------------------
Status CreatGraph(MGraph &G)
{
	printf("input the kind of graph:");
	scanf("%d",&G.Kind);
	switch(G.Kind)
	{
//	 case DG:return CreateDG(G);
//	 case DN:return CreateDN(G);
//	 case UDG:return CreateUDG(G);
	 case UDN:return CreateUDN(G);
	 default: return ERROR; 
	}
}

int main()
{
//	MGraph G;
//	CreateUDN(G);
//	DFSTraverse(G);
	ALGraph M;
	CreatAlgraph(M);
	BFSTraverse(M,Print);
//	Print(2,M); 
}

猜你喜欢

转载自blog.csdn.net/weixin_42673117/article/details/84997536