图------有向网的建立、深度优先遍历,广度优先遍历

#include <stdio.h>
#include <stdlib.h>
#define MAX 20


//    有向网的建立   深度遍历 广度遍历等操作的实现
typedef struct ArcNode
{
   int adjvex;
   int weight;
   struct ArcNode *next;
}ArcNode;


typedef struct VertexNode
{
   char vexdata;
   ArcNode *head;
}VertexNode;


typedef struct
{
    VertexNode vertex[MAX];
    int vexnum;
    int arcnum;
}AdjList;


typedef struct Node{  
    int data[MAX];  
    int front;  
    int order;  
}Queue; 




void Creat(AdjList *G)
{
    int i,weight,vex1,vex2;
    ArcNode *q=NULL;
    printf("请输入有向网中的顶点数和边数:");
    scanf("%d,%d",&G->vexnum,&G->arcnum);
getchar();
    for(i=1;i<=G->vexnum;i++)
    {
          printf("请输入第%d个结点的名称:",i);
          scanf("%c",&G->vertex[i].vexdata);
 getchar();
          G->vertex[i].head=NULL;
     }
     for(i=1;i<=G->arcnum;i++)
     {
          printf("请输入第%d条边的起点和终点以及权值:",i);
          scanf("%d,%d,%d",&vex1,&vex2,&weight);
          q=(ArcNode *)malloc(sizeof(ArcNode));
          q->adjvex=vex2;
          q->weight=weight;
          q->next=G->vertex[vex1].head;
          G->vertex[vex1].head=q;
      }    
}


int visited[MAX];
//深度优先遍历
void DFS(AdjList *G,int i)          
{  
    ArcNode *p;
    visited[i]=1; //设置下标为I的顶点为已访问   
    printf("%c ",G->vertex[i].vexdata); //输出顶点信息
p = G->vertex[i].head; //下一个边表结点
    while(p)  
    {  
        if(!visited[p->adjvex]) //如果是未访问的则递归  
            DFS(G,p->adjvex);  
        p=p->next;  
    }  

 
void DFSTraverse(AdjList *G)  
{   int i;
    for(i=1;i<=G->vexnum;i++) //初始化每个顶点都未访问过  
        visited[i] = 0;
    for(i=1;i<=G->vexnum;i++) //选取一个未访问的顶点,进行深度优先搜索,  
{   
if(visited[i]!=1) //如果是连通图只执行一次  
           DFS(G,i);
}
}


//广度优先遍历
void InitQueue(Queue *q)  
{  
    q->front = q->order = 0;  
    memset(q->data,-1,sizeof(int)*MAX);  

 
int IsEmpty(Queue *q)  
{  
    if(q->order == q->front)  
        return 1;  
    return 0;  

 
void EnQueue(Queue *q,int Element)  
{  
    if((q->order + 1) % MAX == q->front)  
        return;  
    q->data[q->order] = Element;  
    q->order = (q->order + 1) / MAX;  

 
void DeQueue(Queue *q,int *e)  
{  
    if(q->order == q->front)  
        return;  
    *e = q->data[q->front];  
    q->front = (q->front + 1) % MAX;  

 
void BFSTraverse(AdjList *G)  
{  
    int i;
    Queue q;
ArcNode *p;
    InitQueue(&q); //初始化队列  
    for(i=1;i<=G->vexnum;i++) //设置所为顶点为未访问  
        visited[i]=0;  
    for(i=1;i<=G->vexnum;i++)  
    {  
        if(!visited[i]) //选取一个未访问的顶点,如果图是连通图,则只执行一次  
        {  
            visited[i]=1; //设置顶点为已访问  
            printf("%c ",G->vertex[i].vexdata);   
            EnQueue(&q,i); //当前顶点的下标值进队  
            while(IsEmpty(&q)!=1) //队列不为空  
            {  
                DeQueue(&q,&i); //出队  
                p = G->vertex[i].head; //指向下一个边表结点  
                while(p)  
                {  
                    if(!visited[p->adjvex]) //如果是未访问的结点  
                    {  
                        visited[p->adjvex]=1;  
                        printf("%c ",G->vertex[p->adjvex].vexdata);  
                        EnQueue(&q,p->adjvex);  
                    }  
                    p=p->next; //指向下一个边表结点  
                }  
            }  
  
        }  
    }  

   
void DisplayGraph(AdjList *adj)  
{  
    int i;  
    int n=adj->vexnum;//顶点个数,后面要遍历每一个点点  
    ArcNode *q=NULL;  
    for( i=1;i<=n;i++)  
    {    
       q=adj->vertex[i].head;  
        if(q==NULL)//表示头结点后面没有跟其他结点  
        {  
            printf("没有从%c出发的节点\n",adj->vertex[i].vexdata);  
        }  
        else  
        {  
            printf("从结点%c出发的边有:",adj->vertex[i].vexdata);  
            while(q!=NULL)  
            {  
                printf("%c-->%c\n",adj->vertex[i].vexdata,adj->vertex[q->adjvex].vexdata);  
                q=q->next;  
            }  
        }  
    }  
}


void main()
{
     AdjList *G=(AdjList *)malloc(sizeof(AdjList));
     Creat(G); 
     DisplayGraph(G);
     printf("深度优先搜索遍历:\n");  
     DFSTraverse(G);  
     printf("\n");  
     printf("广度优先搜索遍历:\n");  
     BFSTraverse(G);  
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
广度优先搜索(BFS)是遍历算法之一,它可以用来寻找一个中的最短路径,或者判断两个节点之间是否连通,或者找到一个节点的所有邻居等。BFS 的思路是从一个起始节点开始,依次遍历它的所有邻居节点,并将这些邻居节点加入队列中,然后继续遍历队列中的节点,直到队列为空为止。 下面是 BFS 的具体解题思路: 1. 初始化: - 将起点放入队列中; - 标记起点为已访问; 2. 开始遍历: - 取出队列中的第一个节点,即当前节点; - 遍历当前节点的所有邻居节点,如果邻居节点没有被访问过,将其加入队列中,并标记为已访问; - 重复步骤 2,直到队列为空为止。 3. 输出结果: - 遍历完所有节点后,可以输出遍历的结果,比如输出每个节点的深度或者距离起点的最短路径等。 下面是一个示例: 假设有如下的: ``` A -- B -- C | | | D -- E -- F ``` 其中,A、B、C、D、E、F 分别代表节点,每条线段代表它们之间的连接关系。 现在要从节点 A 开始进行 BFS 遍历,以下是具体步骤: 1. 初始化: 将节点 A 放入队列中,标记 A 为已访问。 2. 开始遍历: - 取出队列中的第一个节点 A,遍历它的邻居节点 B 和 D,将它们加入队列中并标记为已访问; - 取出队列中的第二个节点 B,遍历它的邻居节点 A、C 和 E,其中 A 已经被访问过了,所以不需要再次访问;将 C 和 E 加入队列中,并标记为已访问; - 取出队列中的第三个节点 D,遍历它的邻居节点 A 和 E,其中 A 已经被访问过了,所以不需要再次访问;E 已经被访问过了,所以也不需要再次访问; - 取出队列中的第四个节点 C,遍历它的邻居节点 B 和 F,其中 B 已经被访问过了,所以不需要再次访问;将 F 加入队列中,并标记为已访问; - 取出队列中的第五个节点 E,遍历它的邻居节点 B、D 和 F,其中 B 和 D 已经被访问过了,所以不需要再次访问;F 已经被访问过了,所以也不需要再次访问; - 取出队列中的第六个节点 F,遍历它的邻居节点 C 和 E,其中 E 已经被访问过了,所以不需要再次访问;C 已经被访问过了,所以也不需要再次访问; - 队列为空,结束遍历。 3. 输出结果: 遍历的结果可以是每个节点的深度或者距离起点的最短路径等,以下是每个节点的深度: ``` A: 0 B: 1 C: 2 D: 1 E: 2 F: 3 ``` 可以看到,节点 A 的深度为 0,它的邻居节点 B 和 D 的深度为 1,它们的邻居节点 C 和 E 的深度为 2,最后节点 F 的深度为 3。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值