数据结构图的邻接矩阵存储及深度广度优先搜索

#include<stdio.h> 
#include<stdlib.h>
#define INFINITY INT_MAX     /* 最大值∞ */
#define MAX_VEX 20    /*  最大顶点数  */
int  Visited[MAX_VEX];/*  标志数组  */
typedef enum{DG,DN,UDG,UDN} Graphkind;
typedef struct{              //包含权的邻接矩阵的的定义
    int Vertices[MAX_VEX];             //顶点信息的数组
    int arcs[MAX_VEX][MAX_VEX]; //邻接矩阵 
    int vexnum; //当前图的顶点数
    int arcnum; //当前的图边数
    Graphkind kind;
}MGraph;
//函数声明 
void CreateDG(MGraph *G);
void CreateDN(MGraph *G);
void CreateUDG(MGraph *G);
void CreateUDN(MGraph *G);
void DispGraph(MGraph G);
void DFS_traverse_Grapg(MGraph G);
void BFS_traverse_Grapg(MGraph G);
//构造图(选择图的种类)  
void CreateGraph(MGraph *G){
	while(1){
		printf("请输入图的种类(0.有向图 1.有向网 2.无向图 3.无向网):");
	    scanf("%d",&G->kind);
		switch(G->kind) {
		case DG:CreateDG(G);break;
		case DN:CreateDN(G);break;
		case UDG:CreateUDG(G);break;
		case UDN:CreateUDN(G);break;
		default:printf("输入错误,请从新输入!\n"); 
	    }
	    if(G->kind>=0&&G->kind<=3){
    	    DispGraph(*G);
    	    printf("\n");
    	    DFS_traverse_Grapg(*G);
    	    printf("\n");
    	    BFS_traverse_Grapg(*G);
    	    printf("\n******************************************************\n");
	    }        
	}
}
/* 构造时输入弧(边)的顺序会影响打印的邻接表及深、度广度优先搜索  */ 
//有向图 
void CreateDG(MGraph *G) //图的生成函数
{ 
    int vi,vj,w,i,j;
    printf("请输入图的顶点数和弧数(以空格分隔):");
    scanf("%d%d",&G->vexnum,&G->arcnum);
    //图(邻接矩阵)的初始化
    for(i=0;i<G->vexnum;i++) 
        for(j=0;j<G->vexnum;j++)
                G->arcs[i][j]=0;
    //将顶点存入数组中
    for(i=0;i<G->vexnum;i++) 
    { 
        printf("请输入第%d个顶点的信息(整型):",i+1);
        scanf("%d",&G->Vertices[i]);  //以0为位置起点 
    }
    printf("\n");
    //将弧存入邻接矩阵中 
    for(i=0;i<G->arcnum;i++)
    { 
        printf("请输入第%d条弧的信息i,j,w(以空格分隔):",i+1);
        scanf("%d%d%d",&vi,&vj,&w);
		//vi,vj为边或弧的顶点位置信息 
        //若为不带权值的图,则w输入1
        //若为带权值的图,则w输入对应权值
        G->arcs[vi][vj]=w;
    }
//    DispGraph(*G);
}
//有向网 
void CreateDN(MGraph *G) //图的生成函数
{ 
    int vi,vj,w,i,j;
    printf("请输入图的顶点数和弧数(以空格分隔):");
    scanf("%d%d",&G->vexnum,&G->arcnum);
    //图(邻接矩阵)的初始化
    for(i=0;i<G->vexnum;i++) 
        for(j=0;j<G->vexnum;j++)
                G->arcs[i][j]=INT_MAX;
    //将顶点存入数组中    
    for(i=0;i<G->vexnum;i++) 
    { 
        printf("请输入第%d个顶点的信息(整型):",i+1);
        scanf("%d",&G->Vertices[i]);
    }
    printf("\n");
    //将弧存入邻接矩阵中 
    for(i=0;i<G->arcnum;i++)
    { 
        printf("请输入第%d条弧的信息i,j,w(以空格分隔):",i+1);
        scanf("%d%d%d",&vi,&vj,&w); 
        //若为不带权值的图,则w输入1
        //若为带权值的图,则w输入对应权值

        G->arcs[vi][vj]=w;
    }
//    DispGraph(*G);
}

//无向图 
void CreateUDG(MGraph *G) //图的生成函数
{ 
    int vi,vj,w,i,j;
    printf("请输入图的顶点数和边数(以空格分隔):");
    scanf("%d%d",&G->vexnum,&G->arcnum);
    //图(邻接矩阵)的初始化
    for(i=0;i<G->vexnum;i++) 
        for(j=0;j<G->vexnum;j++)
                G->arcs[i][j]=0;
     //将顶点存入数组中
    for(i=0;i<G->vexnum;i++) 
    { 
        printf("请输入第%d个顶点的信息(整型):",i+1);
        scanf("%d",&G->Vertices[i]);
    }
    printf("\n");
    //将边存入邻接矩阵中 
    for(i=0;i<G->arcnum;i++)
    { 
        printf("请输入第%d条边的信息i,j,w(以空格分隔):",i+1);
        scanf("%d%d%d",&vi,&vj,&w); 
        //若为不带权值的图,则w输入1
        //若为带权值的图,则w输入对应权值

        G->arcs[vi][vj]=w;//①
        G->arcs[vj][vi]=w;//②
        //无向图具有对称性的规律,通过①②实现
        //有向图不具备此性质,所以只需要①
    }
//    DispGraph(*G);
}
//无向网 
void CreateUDN(MGraph *G) //图的生成函数
{ 
    int vi,vj,w,i,j;
    printf("请输入图的顶点数和边数(以空格分隔):");
    scanf("%d%d",&G->vexnum,&G->arcnum);
    //图(邻接矩阵)的初始化
    for(i=0;i<G->vexnum;i++) 
        for(j=0;j<G->vexnum;j++)
            G->arcs[i][j]=INT_MAX;
    //将顶点存入数组中       
    for(i=0;i<G->vexnum;i++)
    { 
        printf("请输入第%d个顶点的信息(整型):",i+1);
        scanf("%d",&G->Vertices[i]);
    }
    printf("\n");
    //将边存入邻接矩阵中 
    for(i=0;i<G->arcnum;i++)
    { 
        printf("请输入第%d条边的信息i,j,w(以空格分隔):",i+1);
        scanf("%d%d%d",&vi,&vj,&w); 
        //若为不带权值的图,则w输入1
        //若为带权值的图,则w输入对应权值

        G->arcs[vi][vj]=w;//①
        G->arcs[vj][vi]=w;//②
        //无向网具有对称性的规律,通过①②实现
        //有向网不具备此性质,所以只需要①
    }
//    DispGraph(*G);
}
//输出邻接矩阵的信息
void DispGraph(MGraph G) 
{ 
    int i,j;
    printf("\n输出顶点的信息(整型):");
    for(i=0;i<G.vexnum;i++)
        printf("%8d",G.Vertices[i]);

    printf("\n输出邻接矩阵:\n");
    printf("\t");
    for(i=0;i<G.vexnum;i++)
        printf("%8d",G.Vertices[i]);
    printf("\n"); 
    for(i=0;i<G.vexnum;i++)
    { 
        printf("\n%8d",G.Vertices[i]);
        for(j=0;j<G.vexnum;j++)
        {   
            if(G.arcs[i][j]==INFINITY){
            	printf("%8s","∞");
			}
			else{
				printf("%8d",G.arcs[i][j]);
			}
        }
        printf("\n");   
    }
}
void Visit(int v)
{
	printf("\t%d",v);
}
/*  深度优先搜索(邻接矩阵)  */
void  DFS(MGraph G , int v)
{  int i;
   Visit(v);       /*  访问顶点v  */ 
   Visited[v]=1;   //设置访问标志
   for(i=0;i<G.vexnum;i++){
   	   if((G.arcs[v][i]>=1&&G.arcs[v][i]!=INT_MAX)&&Visited[i]==0){ //G.arcs[v][i]==1只针对图,对网无效 
   	   	    DFS(G,i);
		}
   }  
}
void DFS_traverse_Grapg(MGraph G)
{  int v;
   for (v=0 ; v<G.vexnum ; v++)
       Visited[v]=0;    /*  访问标志初始化  */ 
      //p=G->AdjList[v].firstarc;
   printf("深度优先搜索遍历:");
   DFS(G , 0);
//   for (v=0 ; v<G.vexnum ; v++){
//   	   if (!Visited[v])   /*  对图的每个顶点至多调用一次DFS函数  */
//	       DFS(G , v);
//   }
}
/*  广度优先搜索(邻接矩阵)  */
void BFS_traverse_Grapg(MGraph G){
	int Queue[MAX_VEX];
	int front=0,rear=0;
	int i,k,v,w;
	for(v=0;v<G.vexnum;v++){
		Visited[v]=0;
	}
	printf("广度优先搜索遍历:");
	for(i=0;i<G.vexnum;i++){    /*  连通图仅需从一个1顶点出发即可  */
		v=G.Vertices[i];       /*  取顶点  */
		if(!Visited[v]){         /*   v尚未访问   */
			Queue[++rear]=v;     /*   v入对   */ 
		}
		while (Queue[front]!=Queue[rear]){  /*  队列非空时  */
			w=Queue[++front];    /*  出队  */
            Visited[w]=1;       /*  置访问标志  */
            Visit(w);          /*  访问队首元素  */
            for(k=0;k<G.vexnum;k++){
            	if((G.arcs[v][i]>=1&&G.arcs[v][i]!=INT_MAX)&&Visited[i]==0){  /*  当前顶点未被访问的所有邻结点入队  */
            		Queue[++rear]=k;
				}/*  end if  */
			}/*  end for  */
		}/*  end while  */
	}/*  end for  */
}

void main()
{ 
    MGraph G;
    CreateGraph(&G);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值