图子系统

图子系统

1.实验目的

(1)掌握图邻接矩阵的存储方法。

(2)掌握图深度优先遍历的基本思想。

(3)掌握图广度优先遍历的基本思想。

2.实验内容

(1)编写按键盘输入的数据建立图的邻接矩阵存储。

(2)编写图的深度优先遍历函数。

(3)编写图的广度优先遍历函数。

(4)设计一个选择式菜单如下:

 

                              图  子  系  统               

           **************************************************

            *          1---------更新邻接矩阵                * 

            *          2---------深度优先遍历                * 

            *          3---------广度优先遍历                *

            *          0---------退       出               *  

            **************************************************

   请选择菜单号(0---3):     


附C源程序如下:

#include <stdio.h>
#define GRAPHMAX 10
#define Queuesize 30

typedef struct
{  char vexs[GRAPHMAX];
   int edges[GRAPHMAX][GRAPHMAX];
   int n,e;
}MGraph;

int visited[10];

void CreateMGraph(MGraph *G);

void DFSTraverseM(MGraph *G);
void DFSM(MGraph *G,int i);

void BFSTraverseM(MGraph *G);
void BFSM(MGraph *G,int k);

typedef struct
{  int front;
   int rear;
   int count;
   int data[Queuesize];
}CirQueue;

void InitQueue(CirQueue *Q)
{  Q->front=Q->rear=0;
   Q->count=0;
}

int QueueEmpty(CirQueue *Q)
{
   return Q->count==0;
}

int QueueFull(CirQueue *Q)
{
   return Q->count==Queuesize;
}

void EnQueue(CirQueue *Q,int x)
{
   if(QueueFull(Q))
	  printf("Error! Queue overflow.");
   else
   {  Q->count++;
      Q->data[Q->rear]=x;
	  Q->rear=(Q->rear+1)%Queuesize;
   }
}

int DeQueue(CirQueue *Q)
{  int temp;
   if (QueueEmpty(Q))
   {  printf("Error! Queue underflow.");
      return NULL;
   }
   else
   {  temp=Q->data[Q->front];
      Q->count--;
	  Q->front=(Q->front+1)%Queuesize;
	  return temp;
   }
}

void main() 
{  MGraph *G,a;  //定义a 为一个MGraph 类型结构变量,则 a 的存储单元就确定下来
   char ch1;
   int ch2;
   G=&a;

   printf("\n\t\t 建立一个图的邻接矩阵存储结构:\n");
   CreateMGraph(G);
   

   getchar();
   ch1='y';
   while (ch1=='y'|| ch1=='Y')
  {
	 printf("\n");
	 printf("\n\t\t                   图  子  系  统                 ");
	 printf("\n\t\t**************************************************");
     printf("\n\t\t*          1---------更新邻接矩阵                *");  
	 printf("\n\t\t*          2---------深度优先遍历                *");  
     printf("\n\t\t*          3---------广度优先遍历                *");  
     printf("\n\t\t*          0---------退        出                *"); 	 
     printf("\n\t\t**************************************************");
     printf("\n\t\t   请选择菜单号(0---3):            ");
	 scanf("%d",&ch2);
	 getchar();
	 switch(ch2)
	 {   case 1:
	           CreateMGraph(G);
			   printf("\n\t\t 图的邻接矩阵存储结构建立完毕.");
			   break;
	     case 2:
               DFSTraverseM(G);
			   break;
         case 3:	
		  	   BFSTraverseM(G);
			   break;  
		 case 0:
			   ch1='n';
			   break;
		 default:
			   printf("\n\t\t 输入错误!请重新输入  ");
	 }
  }
}


void CreateMGraph(MGraph *G)  //建立图的邻接矩阵存储
{ int i,j,k;
  char ch1,ch2;

  printf("\n\t\t 请输入顶点数,边数并按回车(格式如:3,4):");
  scanf("%d,%d",&(G->n),&(G->e));  //输入顶点数,边数

  for (i=0; i<G->n; i++) //输入各顶点符号
  { 
	 getchar();
	 printf("\n\t\t 请输入第 %d 个顶点并按回车:  ",i+1);
	 scanf("%c", &(G->vexs[i]));
  }
  
  for(i=0; i<G->n; i++)
     for(j=0; j<G->n; j++)
		 G->edges[i][j]=0;

  for(k=0;  k<G->e; k++)
  {  getchar();
     printf("\n\t\t 请输入第 %d 条边的顶点符号(格式为:顶点符号,顶点符号):",k+1);
	 scanf("%c,%c",&ch1,&ch2);
	 for(i=0;ch1!=G->vexs[i];i++);
	 for(j=0;ch2!=G->vexs[j];j++);
	 G->edges[i][j]=1;
  }

  printf("\n\t\t 已建立一个图的邻接矩阵存储结构!现输出此邻接矩阵如下:\n");
  for(i=0; i<G->n; i++)  //输出此邻接矩阵
  {  printf("\n\t\t");
     for(j=0; j<G->n; j++)
		printf("%5d",G->edges[i][j]);
  }

}

void DFSTraverseM(MGraph *G) //深度优先遍历
{ int i;
  for(i=0; i<G->n; i++)
	  visited[i]=0;

  for(i=0; i<G->n; i++)
	  if(!visited[i])
		  DFSM(G,i);
}

void DFSM(MGraph *G,int i)  
{ int j;
  printf("\n\t\t 深度优先遍历序列:%c\n", G->vexs[i]);
  visited[i]=1;
  for(j=0; j<G->n; j++)
     if( G->edges[i][j]==1 && !visited[j])
        DFSM(G,j); // 递归调用DFSM(),直到没有未被访问的相邻顶点,则访问后返回到上一层
}

void BFSTraverseM(MGraph *G)
{ int i;
  for(i=0; i<G->n; i++)
	  visited[i]=0;

  for(i=0; i<G->n; i++)
	  if(!visited[i])
		BFSM(G,i);
}

void BFSM(MGraph *G, int k)
{ int i,j;
  CirQueue Q; //定义 Q 为一个循环队列结构变量

  InitQueue(&Q);

  printf("\n\t\t  广度优先遍历序列:  %c\n", G->vexs[k]);  //访问此顶点
  visited[k]=1;  // 将该顶点的访问标志置为已访问
  EnQueue(&Q,k);  // 将该顶点的序号进对
  
  while( !QueueEmpty(&Q) )
  {  i=DeQueue(&Q); //已访问顶点的序号从对首出对
     for(j=0; j<G->n; j++)
	   if( G->edges[i][j]==1 && !visited[j] )  //如果 j 是 i 的邻接点并且 j 未被访问过
	   {  printf("\n\t\t  广度优先遍历序列:  %c\n", G->vexs[j]); 
		  visited[j]=1;
          EnQueue(&Q,j); // j 被访问后进对尾
	   }
  }
}





  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值