基于广度优先搜索,判别以邻接表方式存储的有向图是否有顶点v到顶点u的路径。

30 篇文章 11 订阅
24 篇文章 1 订阅

广度优先 目标边编号(类似 层序遍历)

层序,先序,广度 考虑 队列

深度,后序 考虑栈

//基于广度优先搜索,判别以邻接表方式存储的有向图是否有顶点v到顶点u的路径。
 
#include <stdio.h>
#include <malloc.h>
#include <queue>//队列实现广度优先 
using namespace std;
#define N 11
typedef struct node{
	int aimdex;//箭头指向结点的编号 
	struct node *next;//指向下一个结点 
}node;
 
typedef struct listnode{
	int index;   //结点编号 
	int outdegree;//出度
	node *first; //第一个 边结点 (用 头插法 建立)
}listnode;
 
//构建 邻接表,同时统计 每个结点的 出度 
int len = sizeof(node);//便于 申请 结点空间 

void create_list(listnode a[]);

//广度优先 目标边编号(类似 层序遍历)
int node_flag[N + 1] = {0};//结点 编号 入队标识 
int flag = 0;//找到标识 
void bfs(listnode a[],int v,int w)
{	
	if(v == w)//自己判断自己 这里不再考虑范围(当然也可以改进 用于判环) 
	{
		printf("v和w一样!");
		return;
	}
	
	queue<node*> q1;//队列
	node *p = a[v - 1].first;//创建的时候 v - 1(编号-1为 结点的位置) 
	//将v结点的 所有边结点入队  
	while(p != NULL)
	{
		q1.push(p);
		node_flag[p->aimdex] = 1;//标识入队 
		p = p->next;
	}
	
	node *q;
	while(q1.empty() == 0)//不为空 
	{
		p = q1.front();//p指向队首 结点 
		q1.pop();//队首 出队
		if(p->aimdex == w)//是否是要找的 结点 
		{
			printf("存在");
			flag = 1;//找到标识 
			break;//中断 循环 
		}
		
		//否则将 以队首结点 为出发结点的边结点入队,继续寻找 
		q = a[p->aimdex - 1].first;
		
		while(q != NULL)
		{
			//如果之前该编号边结点 入过队,跳过该结点 
			if(node_flag[q->aimdex] == 1)
			{
				q = q->next;
				continue;
			}
			//否则 入队
			q1.push(q);
			q = q->next; 
		}
	}
	
	return;
}
/*
test
结点编号 出度 边结点 
v1        3   -->4-->3-->2
v2        0         
v3        2   -->5-->2
v4        1   -->5
v5        0
v6        2   -->5-->4
*/
int main()
{
	listnode a[N] = {0,0,NULL};
	//构建 邻接表,同时统计 每个结点的 出度 
	create_list(a);
	//输入要判断 存在 的边
	int v,w;
	v = w = 0;
	printf("v,w: ");
	scanf("%d%d",&v,&w);
	//找到 对应边结点的 表头,往广度 
	bfs(a,v,w);
	
	if(flag == 0)
	{
		printf("不存在!");
	}
	return 0;
}
//输入 创建邻接表 
void create_list(listnode a[])
{
	listnode *p = a;//表结点 
	node *q;//指向边结点 
	//初始 N个 表结点 
	for(int i = 0;i < N;i ++)
	{
		p[i].index = i + 1;//1~n编号
		p[i].outdegree = 0;
		p[i].first = NULL;
	}
	
	//建立 边结点 
	printf("\nplease input the edge node(箭头尾部&头部(编号)(0,0)为结束):\n");
	int k = 0,m = 0;
	scanf("%d%d",&k,&m);//k为 有向边,箭头尾部,m为 头部,编号 
	
	while(k != 0 && m != 0)//输入(0,0)结束
	{
		
		q = (node*)malloc(len);
		
		q->aimdex = m;//标识所指 结点编号
		//头插法 思想
		q->next = p[k - 1].first;//本次结点next 指向上次插入的那个结点(没有就指向 NULL) 
		p[k - 1].first = q;//头插法 新的 边结点 插入单链表的表头 
		
		p[k - 1].outdegree ++;//出度 增加
		
		scanf("%d%d",&k,&m);
	}
	return;
}

  • 2
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,根据您的要求,我会回答您的问题,并且不会透露您的任何要求。 基于深度优先搜索的算法判断有向图是否存在顶点Vi到顶点Vj的路径,可以遵循以下步骤: 1. 从Vi开始进行深度优先搜索,遍历所有可能的路径,在此过程记录访问过的节点。 2. 在遍历的过程,如果遇到Vj节点,则返回true,表示存在一条从Vi到Vj的路径。 3. 如果搜索完所有可能的路径后,仍未找到Vj节点,则返回false,表示不存在从Vi到Vj的路径。 下面是基于深度优先搜索的算法的伪代码: ``` function dfs_search(graph, start, end, visited): if start == end: return True visited.add(start) for neighbor in graph[start]: if neighbor not in visited: if dfs_search(graph, neighbor, end, visited): return True return False ``` 其,graph为邻接表存储有向图,start为起始节点Vi,end为目标节点Vj,visited为访问过的节点集合。 基于广度优先搜索算法判断有向图是否存在顶点Vi到顶点Vj的路径,可以遵循以下步骤: 1. 创建一个队列,将起始节点Vi加入队列。 2. 定义一个visited集合,用于记录访问过的节点。 3. 从队列取出一个节点,遍历该节点所有的邻居节点,如果该邻居节点没有被访问过,则将其加入队列,并将其加入visited集合。 4. 重复执行步骤3,直到队列为空或者找到目标节点Vj。 下面是基于广度优先搜索算法的伪代码: ``` function bfs_search(graph, start, end): visited = set() queue = [start] while queue: node = queue.pop(0) if node == end: return True visited.add(node) for neighbor in graph[node]: if neighbor not in visited: queue.append(neighbor) visited.add(neighbor) return False ``` 其,graph为邻接表存储有向图,start为起始节点Vi,end为目标节点Vj。 这就是基于深度优先搜索和广度优先搜索算法判断有向图是否存在顶点Vi到顶点Vj的路径的伪代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值