数据结构上机作业(c++)—— 图的深度优先搜索和广度优先搜索

题目概述

21.建立输的存储结构(邻接表),输入任意的图,显示图的深度优先搜索的遍历路径
22.建立输的存储结构(邻接表),输入任意的图,显示图的广度优先搜索的遍历路径

算法分析

深度优先搜索:从图中某个顶点V0 出发,访问此顶点,然后依次从V0的各个未被访问的邻接点出发深度优先搜索遍历图,直至图中所有和V0有路径相通的顶点都被访问到。
广度优先搜索:从图中的某个顶点V0出发,并在访问此顶点之后依次访问V0的所有未被访问过的邻接点,之后按这些顶点被访问的先后次序依次访问它们的邻接点,直至图中所有和V0有路径相通的顶点都被访问到。若此时图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。

c++代码

/*
21.建立输的存储结构(邻接表),输入任意的图,显示图的深度优先搜索的遍历路径 
22.建立输的存储结构(邻接表),输入任意的图,显示图的广度优先搜索的遍历路径 
*/ 
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#define CAPACITY 10  	 //循环队列的存储容量 
#define MaxVertexNum 100 //最大的定点数 
#define FALSE 0
#define TRUE 1
/******************************队列*************************************/ 
//存储结构 -循环队列 
typedef int ElemType;  
typedef struct   
{  
    int front;  
    int rear;  
    int size;  
    ElemType data[CAPACITY];  
}Queue;  

//初始化队列 
Queue* initQueue()  
{  
    Queue *q = NULL;  
    q = (Queue*)malloc(sizeof(Queue));  
    if(q == NULL)  
        return NULL;   
    memset(q->data, 0, CAPACITY);  
    q->front = q->rear = 0;  
    q->size = 0;  
    return q;  
}  

//入队 
bool enQueue(Queue* q, ElemType data)  
{  
    if(q == NULL)  
        return FALSE;  
    if(q->size == CAPACITY)  
        return FALSE;  
    q->data[q->rear] = data;  
    q->rear = (q->rear+1) % CAPACITY;  
    q->size++;  
      
    return TRUE;  
}  

//出队 
ElemType deQueue(Queue* q)  
{  
    ElemType res;  
    if(q == NULL)  
        exit(0);  
    if(q->size == 0)  
        return FALSE;  
    res = q->data[q->front];  
    q->front = (q->front+1) % CAPACITY;  
    q->size--;  
      
    return res;  
}  
 
/*******************************邻接表********************************/ 
//存储结构 
bool visited[MaxVertexNum];  //记录该结点是否访问过   
typedef char VertexType;    
typedef int EdgeType;    

typedef struct node     //边表结点    
{    
    int adjvex;         //邻接点域    
    struct node* next;  //域链    
    //若是要表示边上的权,则应增加一个数据域    
}EdgeNode;   
 
typedef struct vnode    //顶点边结点    
{    
    VertexType vertex;  //顶点域    
    EdgeNode* firstedge;//边表头指针    
}VertexNode;   

typedef VertexNode AdjList[MaxVertexNum];   //AdjList是邻接表类型   
 
typedef struct     
{    
    AdjList adjlist;    //邻接表    
    int n;              //图中当前顶点数  
    int e;              //图中当前边数    
}ALGraph;              

//创建邻接表 
ALGraph* creatALGraph()       
{  
    ALGraph* a = NULL;  
    EdgeNode* e = NULL;  
    int i, j, k;  
    char v1, v2;      
    printf("请输入顶点数和边数: \n");  
    scanf("%d%d", &i, &j);  
    if(i<0 || j<0)  
        return NULL;  
    a = (ALGraph*)malloc(sizeof(ALGraph));  
    if(a == NULL)  
        return NULL;  
    a->n = i;  
    a->e = j;  
           
    for(i=0;  i<a->n; i++)  
    {  
        printf("请输入第%d个顶点的信息: ",i+1);   
        getchar(); 
        scanf("%c",&(a->adjlist[i].vertex)); // 读入顶点信息       
        a->adjlist[i].firstedge=NULL;        // 点的边表头指针设为空    
    }  
    for(k=0; k<a->e; k++)  
    {  
        printf("请输入边的信息: ");  
		getchar(); 
        scanf("%c,%c", &v1, &v2);  
        for(i=0; v1!=a->adjlist[i].vertex; i++); //找到顶点v1对应的存储序号 i  
        for(j=0; v2!=a->adjlist[j].vertex; j++); //找到顶点v2对应的存储序号 j
        //将顶点v1添加到邻接表中 
        e = (EdgeNode*)malloc(sizeof(EdgeNode));  
        e->adjvex = i;  
        e->next = a->adjlist[j].firstedge;  
        a->adjlist[j].firstedge = e;  
        //将顶点v2添加到邻接表中 
        e = (EdgeNode*)malloc(sizeof(EdgeNode));  
        e->adjvex = j;  
        e->next = a->adjlist[i].firstedge;  
        a->adjlist[i].firstedge = e;  
    }  
    return a;  
} 

//寻找u结点在顶点表中的编号     
int LocateVex(ALGraph G, VertexType u)
{
	int i;
	for(i=0; i<G.n; i++)
	{
		if(G.adjlist[i].vertex==u)
			return i;
	}
	return -1;
}

//返回v的第一个邻接顶点序号
int FirstAdjVex(ALGraph* G,int i )
{
	EdgeNode *p;
	if(i!=-1 && G->adjlist[i].firstedge)
		return G->adjlist[i].firstedge->adjvex;
	return -1;
} 

//返回v相对于w的下一个邻接顶点序号
int NextAdjVex(ALGraph* G, int i,int j)
{
	node *p, *q;
	if(i!=-1&& j!=-1)
	{
		for(p=G->adjlist[i].firstedge; p; p=p->next)
		{
			if(p->adjvex==j)
			{
				if(p->next)
					return p->next->adjvex;
				else
					return -1;	
			}
		}	
	}
	return -1;									//结点v和结点w并不连通 
} 
//深度优先搜索   
bool DFS(ALGraph* a, int i)  
{  
    if(a == NULL)  
        return FALSE;  
    printf("%c ", a->adjlist[i].vertex);  //访问该结点,并打印输出 
    visited[i] = TRUE; 
    int j;
	for(j=FirstAdjVex(a,i);j>=0;j=NextAdjVex(a,i,j)) 
	{
		if(!visited[j])  
        	DFS(a, j);  //访问尚未访问的且与其邻接的顶点 		
	}
    return TRUE;  
}  
bool DFSTraverse(ALGraph* a)  
{  
    int i;  
    if(a == NULL)            //空图 
        return FALSE;  
    for(i=0; i<a->n; i++)    //初始化,所有的结点均未被访问 
        visited[i] = FALSE;  
    for(i=0; i<a->n; i++)  //对于每一个未被访问的结点进行深度优先搜索遍历 
        if(!visited[i])  
            DFS(a, i);  
    return TRUE;  
}    

//广度优先搜索 
bool BFS(ALGraph* a, int i)  
{  
    int j, k;  
    Queue *q = NULL;  
    EdgeNode *e = NULL;  
    if(a == NULL)  
        return FALSE;  
    q = initQueue();  
    if(!visited[i])  
    {  
        printf("%c ", a->adjlist[i].vertex);  
        visited[i] = TRUE;  
    }  
    j = a->adjlist[i].firstedge->adjvex;  
    e = a->adjlist[i].firstedge->next;  
    if(!visited[j])  
    {  
        enQueue(q, j);  
        while(e)  
        {         
            k = e->adjvex;  
            if(!visited[k])  
            {  
                enQueue(q, e->adjvex);  
                printf("%c ", a->adjlist[k].vertex);  
                visited[k] = TRUE;  
            }  
            e = e->next;  
        }  
    }  
    while(q->size != 0)  
    {  
        j = deQueue(q);  
        BFS(a, j);  
    }  
      
}  
bool BFSTraverse(ALGraph* a)  
{  
    int i;  
    if(a == NULL)  
        return FALSE;  
    for(i=0; i<a->n; i++)  
        visited[i] = FALSE;  
    for(i=0; i<a->n; i++)  
        BFS(a, i);  
    return TRUE;  
}  
int main()
{
	ALGraph* a = creatALGraph(); 
	printf("************深度优先搜索算法***********\n"); 
    DFSTraverse(a);
    printf("\n"); 
	printf("************广度优先搜索算法***********\n");  
	BFSTraverse(a);
	printf("\n");
    return 0;   
 } 
 
 /*
 8 8
 A
 B
 C
 D
 E
 F
 G
 H
 A,B
 A,C
 B,D
 B,E
 C,F
 C,G
 D,H
 E,H
 
 */

测试用例

  • 测试用例一

在这里插入图片描述
在这里插入图片描述

  • 测试用例二
    在这里插入图片描述

在这里插入图片描述

  • 测试用例三
    在这里插入图片描述

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zyw2002

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值