数据结构之图的应用

该博客介绍了如何实现图的深度优先和广度优先搜索遍历,包括邻接矩阵和邻接表两种存储结构。通过用户指定的顶点,程序展示无向连通图的遍历过程,并输出遍历节点序列。实验要求使用C语言完成,同时编写实验报告和算法设计小结。
摘要由CSDN通过智能技术生成


实验四   图的应用

一、 实验题目:

图的应用——深度优先和广度优先搜索遍历

二、 实验内容:

很多涉及图上操作的算法都是以图的遍历操作为基础的。试编写程序,实现图的深度优先和广度优先搜索遍历操作。

要求:分别以邻接矩阵和邻接表作为存储结构,以用户指定的顶点为起始点,实现无向连通图的深度优先及广度优先搜索遍历,并输出遍历的结点序列。

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

三、 实验要求:

1. 使用C语言完成算法设计和程序设计并上机调试通过。

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

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

四、 程序源代码:

#include<stdio.h>

#include<stdlib.h>

#define maxsize 20

#define TRUE 1

#define FALSE 0

int n,e;

char MG[20];

//广度的结构体定义

typedef struct {

   char vexs[maxsize];

   int arcs[maxsize][maxsize];

}MGraph;

 

typedef struct {

   char data[maxsize];

   int front,rear;

}LinkQueue;

 

typedef struct ArcNode{

   int adjvex;

   struct ArcNode *nextarc;

}ArcNode;

 

typedef struct{

char  data;

    ArcNode *firstarc;

}VNode;

VNode g[maxsize];

MGraph G;

LinkQueue Q;

 

int Locate(char v)

{

int i;

for(i=1;i<n;i++)

if(MG[i]==v) return i;

}

 

bool QueueEmpty(LinkQueue &Q)  {

if(Q.front==Q.rear) return true;

else    

return false;

}

 

int  EnQueue(LinkQueue &Q,int k){

 if(Q.front==(Q.rear+1)%maxsize){

 printf("队列已满!\n");

     return FALSE;

 }

 else{

 Q.rear=(Q.rear+1)%maxsize;

     Q.data[Q.rear]=k;

 }

}

int DeQueue(LinkQueue &Q){

 if(QueueEmpty(Q)){

  printf("队列为空,无法出队!\n");

  return FALSE;

   }

 else{

  Q.front=(Q.front+1)%maxsize;

  return Q.data[Q.front];

 }

 return 1;

}

void print()

{

 int i,j;

 printf("\n对应的邻接矩阵是:\n\n");

 for(i=1;i<=n;i++)

 {

  for(j=1;j<=n;j++)

  printf("%5d",G.arcs[i][j]);

  printf("\n");

 

 }

}

//邻接表构造无向图

void CreateDG()

{

 int i,j,k;

 ArcNode *s;

 char ch,v1,v2;

 printf("请输入顶点信息:  ");

 scanf("%c",&ch);

 for(i=1;i<=n;i++)

 {  MG[i]=getchar();

  G.vexs[i] =g[i].data=i;

  g[i].firstarc=NULL;

 }

 for(i=1;i<=n;i++)

 for(j=1;j<=n;j++)

   G.arcs[i][j]=0;

 printf("输入边结点<v1 v2>信息:\n");

 getchar();

 for(k=1;k<=e;k++){

      scanf("%c%c",&v1,&v2);

 getchar();

 j=Locate(v1);

 i=Locate(v2);

      s=(ArcNode *)malloc(sizeof(ArcNode));

      s->adjvex=j;

      s->nextarc=g[i].firstarc;

      g[i].firstarc=s;

      s=(ArcNode *)malloc(sizeof(ArcNode));

      s->adjvex=i;

      s->nextarc=g[j].firstarc;

      g[j].firstarc=s;

      G.arcs[i][j]=1;

      G.arcs[j][i]=1;

    }

}

void println(){

 int i;

 ArcNode *s;

 printf("\n对应的邻接表是:\n");

 for(i=1;i<=n;i++){

   s=g[i].firstarc;

   printf("%3c",MG[g[i].data]);

   while(s!=NULL){

   printf("%5d",s->adjvex);

   s=s->nextarc;

   }

   printf("\n");

 }

}

//邻接矩阵广度优先遍历

void BFS(int i){

  int j;

  int visited[maxsize]={0};

  printf("%3c",MG[G.vexs[i]]);

  visited[i]=TRUE;

  EnQueue(Q,i);

  while(!QueueEmpty(Q))

  {

  i=DeQueue(Q);

  for(j=1;j<=n;j++)

  if((G.arcs[i][j]==1)&&(!visited[j])){

     printf("%3c",MG[G.vexs[j]]);

     visited[j]=TRUE;

     EnQueue(Q,j);

   }

 }

}

//邻接矩阵深度优先遍历

void  DFS(int i){

   int j;

   static int visited[maxsize]={0};

   printf("%3c",MG[G.vexs[i]]);

   visited[i]=TRUE;

   for(j=1;j<=n;j++)

   if((G.arcs[i][j]==1)&&(!visited[j]))

  DFS (j);

}

//邻接表的广度优先遍历

void BFSL(int k){

int i;

   int visited[maxsize]={0};

   ArcNode *p;

   printf("%3c",MG[g[k].data]);

   visited[k]=TRUE;

   EnQueue(Q,k);

   while(!QueueEmpty(Q)){

   i=DeQueue(Q);

       p=g[i].firstarc;

   while(p!=NULL){

   if(!visited[p->adjvex]){

   printf("%3c",MG[g[p->adjvex].data]);

           visited[p->adjvex]=TRUE;

           EnQueue(Q,p->adjvex);

           }   

   p=p->nextarc;  

        }

     }

}

//邻接表的深度优先遍历

void DFSL(int k){

 int j;

 ArcNode *p;

 static int visited[maxsize]={0};

 printf("%3c",MG[g[k].data]);

 visited[k]=TRUE;

 p=g[k].firstarc;

 while(p){

  j=p->adjvex;

  if(!visited[j])

  DFSL(j);

  p=p->nextarc;

 }

}

void main()

{

  int i,k,ch;char v;

  printf("1.邻接表无向图\n");

  printf("2.邻接表广度优先遍历\n");

  printf("3.邻接表深度优先遍历\n");

  printf("4.邻接矩阵\n");

  printf("5.邻接矩阵广度优先遍历\n");

  printf("6.邻接矩阵深度优先遍历\n");

  printf("7.退出程序\n");

  printf("输入结点及边的数目:\n");

  scanf("%d %d",&n,&e);

  while(1){

printf("\n输入选择: ");

     scanf("%d",&ch);

  switch(ch){

  case 1:

  CreateDG();

      println();

  break;

  case 2:

  printf("\n邻接表广度优先遍历后得到的序列是:\n ");

  printf("从哪个结点开始: ");

   getchar();

      scanf("%c",&v);

  BFSL(Locate(v));

  break;

  case 3:

  printf("\n邻接表深度优先遍历后得到的序列是:\n ");

  printf("从哪个结点开始: ");

   getchar();

      scanf("%c",&v);

  DFSL(Locate(v));

  break;

  case 4:

      print();

  break;

  case 5:

  printf("\n邻接矩阵广度优先遍历后得到的序列是: \n");

  printf("从哪个结点开始: ");

  getchar();

      scanf("%c",&v);

  BFS(Locate(v));

  break;

  case 6:

  printf("\n邻接矩阵深度优先遍历后得到的序列是:\n ");

  printf("从哪个结点开始: ");

  getchar();

      scanf("%c",&v);

  DFS(Locate(v));

  break;

  case 7:exit (0);

       }

    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值