C语言实现的图的深度搜索与广度搜索程序

/*

上机试验5-图的建立和遍历

1)建立【无向】【非连通】图的邻接表存储结构,要求顶点个数不少于15个。

2)用DFS及BFS对此邻接表进行遍历,打印出两种遍历的顶点访问顺序。

3)给定图中任意两个顶点v1和v2及整数k,判断是否存在从v1到v2的路径长度为k的简单路径,若有打印出路径上的顶点序列(要求路径上不含回路)。

进一步:找出从v1到v2的所有路径长度为k的【简单】路径。(简单路径是指:顶点序列中不含【重现】的顶点的路径。)

*/

#include<memory>

#include<cstdio>

#include<malloc.h>

#define PointNum 15

using namespace std;

struct V{

int vertex;

int distance;

int sign;

struct V* next;

}Vertex[PointNum+1];

int P[PointNum];

int union_find(int x) // 并查集

{

while(P[x]!=x)x=P[x];

return x;

}

void DFS(int vertex_);

void BFS(int vertex_);

int DFS(int V1,  int V2, int V3, int kn);

int lujing[PointNum+1],lujing_I;

int main()

{

int times,vertexNumbers,edgeNumbers,i,j,V1,V2,Distance,n=1,v1,v2,kn;

struct V *p,*q,*temp;

printf("请输入您所要进行的测试次数:");

scanf("%d",&times);

while(times--)

{

printf("\n第%d组数据输入.\n",n++);

printf("请输入顶点数:");

scanf("%d",&vertexNumbers); //要保证vertexNumbers <= PointNum

for( i = 0 ; i < vertexNumbers ; i ++ )

{

Vertex[i].vertex = i;//////////////////////////

Vertex[i].distance = 0;////////////////////////

Vertex[i].sign = 0;

Vertex[i].next = NULL;

}

printf("请输入边数:");

scanf("%d",&edgeNumbers); //要保证vertexNumbers <= PointNum

for( i = 0 ; i < edgeNumbers ; i ++ )

{

printf("请输入数据:");

scanf("%d%d%d",&V1,&V2,&Distance);

p = &Vertex[V1];q = Vertex[V1].next;

while( q != NULL ){

p = q;

q = q->next;

}//出来的时候q指向Vertex[V1]邻接表的结尾-NULL,

temp = (struct V *)malloc(sizeof(Vertex[0]));

p->next = temp;  temp->next = NULL;//接上temp

temp->vertex = V2; temp->distance = Distance;temp->sign = 0;   //给temp赋值

p = &Vertex[V2];q = Vertex[V2].next;

while( q != NULL ){

p = q;

q = q->next;

}

temp = (struct V *)malloc(sizeof(Vertex[0]));///////////temp的问题???????

p->next = temp;  temp->next = NULL;//接上temp

temp->vertex = V1;temp->distance = Distance;temp->sign = 0;   //给temp赋值

}

for(i = 0 ; i < vertexNumbers ; i ++ )

{

printf("\nDFS遍历的顶点访问顺序 :");

DFS(i);

for(int j = 0 ; j < vertexNumbers ; j ++ )

{

Vertex[j].sign = 0;

}

}

printf("\n");

for(i = 0 ; i < vertexNumbers ; i ++ )

{

for(int j = 0 ; j < vertexNumbers ; j ++ )

{

Vertex[j].sign = 0;

}

printf("\nBFS遍历的顶点访问顺序 :");

BFS(i);

}

for(j = 0 ; j < vertexNumbers ; j ++ )

{

Vertex[j].sign = 0;

}

printf("输入v1、v2及整数kn :\n");

scanf("%d%d%d",&v1,&v2,&kn);

for(j = 0 ; j < vertexNumbers ; j ++ )

{

Vertex[j].sign = 0;

}

lujing_I = 0;

DFS(v1,v2,v1,kn);

}

return 0;

}

void BFS(int vertex_)

{

struct V *p = &Vertex[vertex_];

int others[PointNum];

do{

if(Vertex[p->vertex].sign == 0){

printf("%d->",p->vertex);//输出访问节点

Vertex[p->vertex].sign = 1;//代表已经访问过了//

others[p->vertex] = -1;//代表这一个可以继续进行BFS

}

else others[p->vertex] = p->vertex;//记录已有的点

p = p->next;//主要

}while(p != NULL);

p = &Vertex[vertex_];

while( p->next != NULL )//有些没有连接要考虑~~!!!!!!!

{

p = p->next;

if(others[p->vertex] == -1)BFS(p->vertex);

}

}

void DFS(int vertex_)

{

struct V *q = Vertex[vertex_].next;//开始的:p = &Vertex[i];q = Vertex[i].next;

Vertex[vertex_].sign = 1;//代表已经访问过了

printf("%d->",vertex_);//

do{

for(;q != NULL && Vertex[q->vertex].sign == 1;q = q->next);//判断节点是否已经访问过了//原来是q->next != NULL//很大的错误:::::::::::::::Vertex[q->vertex].sign == 1不能用:::q.sign == 1(********************

if(q == NULL )return;//(q->next == NULL && vertex_Sum == vertexNumbers)

else DFS(q->vertex);//从q->vertex继续深搜索 *********************q->sign居然没有赋初值!!!! //很大的错误:::::::::::::::Vertex[q->vertex].sign == 1不能用:::q->sign == 1(**************

}while( q != NULL );//有些没有连接要考虑~~!!!!!!!!

}

int DFS(int V1,  int V2, int V3, int kn)

{

struct V *q = Vertex[V1].next;//开始的

int sum,i;

Vertex[V1].sign = 1;//代表已经访问过了

lujing[lujing_I ++ ] = V1;//printf("%d->",V1);//

if(V1 == V2)

{

for(sum=0,i=0; i < lujing_I; i++)

{

if(i >= 1 )//从第二个点开始

{

for(q = &Vertex[lujing[i-1]]; q != NULL; q = q->next)

{

if( q->vertex == lujing[i])sum += q->distance;

}

}

}

if(kn==sum)

{

printf("%d到%d距离为%d的路径为:",V3,kn,sum);

for(i=0; i < lujing_I; i++)

{

printf("%d->",lujing[i]);

}

printf("%d\n",sum);

}

//return sum;

}

do{

for(;q != NULL && Vertex[q->vertex].sign == 1;q = q->next);//判断节点是否已经访问过了//原来是q->next != NULL//很大的错误:::::::::::::::Vertex[q->vertex].sign == 1不能用:::q.sign == 1(********************

if(q == NULL )return -1;//(q->next == NULL && vertex_Sum == vertexNumbers)

else {

DFS(q->vertex,V2,V3,kn);//从q->vertex继续深搜索 *********************q->sign居然没有赋初值!!!! //很大的错误:::::::::::::::Vertex[q->vertex].sign == 1不能用:::q->sign == 1(**************

Vertex[q->vertex].sign = 0;lujing_I -- ;q = q->next;

}

}while( q != NULL );//有些没有连接要考虑~~!!!!!!!!

return 0;

}

/*

输入:

10

4

4

0 1 34

0 2 55

1 3 55

2 3 34

0 3 89

5

5

0 1 1

0 3 1

0 4 1

1 2 1

1 3 1

7

10

0 1 12

0 4 34

1 2 43

1 5 543

2 3 54

2 4 54

2 5 54

3 6 64

4 5 64

5 6 654

15

16

0 1 1

1 2 1

1 10 1

2 3 1

3 4 1

4 5 1

5 6 1

6 7 1

6 14 1

7 8 1

8 9 1

9 10 1

10 11 1

11 12 1

12 13 1

13 14 1

5

5

5 4 12

0 1 12

0 2 32

3 0 43

4 0 43

输出:

DFS遍历的顶点访问顺序 :0 -> 1 -> 2 -> 3 -> 4 ->

DFS遍历的顶点访问顺序 :1 -> 0 -> 3 -> 4 -> 2 ->

DFS遍历的顶点访问顺序 :2 -> 1 -> 0 -> 3 -> 4 ->

DFS遍历的顶点访问顺序 :3 -> 0 -> 1 -> 2 -> 4 ->

DFS遍历的顶点访问顺序 :4 -> 0 -> 1 -> 2 -> 3 ->

BFS遍历的顶点访问顺序 :0 -> 1 -> 3 -> 4 -> 2 ->

BFS遍历的顶点访问顺序 :1 -> 0 -> 2 -> 3 -> 4 ->

BFS遍历的顶点访问顺序 :2 -> 1 -> 0 -> 3 -> 4 ->

BFS遍历的顶点访问顺序 :3 -> 0 -> 1 -> 4 -> 2 ->

BFS遍历的顶点访问顺序 :4 -> 0 -> 1 -> 3 -> 2 ->

DFS遍历的顶点访问顺序 :0 -> 1 -> 2 -> 3 -> 6 -> 5 -> 4 ->

DFS遍历的顶点访问顺序 :1 -> 0 -> 4 -> 2 -> 3 -> 6 -> 5 ->

DFS遍历的顶点访问顺序 :2 -> 1 -> 0 -> 4 -> 5 -> 6 -> 3 ->

DFS遍历的顶点访问顺序 :3 -> 2 -> 1 -> 0 -> 4 -> 5 -> 6 ->

DFS遍历的顶点访问顺序 :4 -> 0 -> 1 -> 2 -> 3 -> 6 -> 5 ->

DFS遍历的顶点访问顺序 :5 -> 1 -> 0 -> 4 -> 2 -> 3 -> 6 ->

DFS遍历的顶点访问顺序 :6 -> 3 -> 2 -> 1 -> 0 -> 4 -> 5 ->

BFS遍历的顶点访问顺序 :0 -> 1 -> 4 -> 2 -> 5 -> 3 -> 6 ->

BFS遍历的顶点访问顺序 :1 -> 0 -> 2 -> 5 -> 4 -> 3 -> 6 ->

BFS遍历的顶点访问顺序 :2 -> 1 -> 3 -> 4 -> 5 -> 0 -> 6 ->

BFS遍历的顶点访问顺序 :3 -> 2 -> 6 -> 1 -> 4 -> 5 -> 0 ->

BFS遍历的顶点访问顺序 :4 -> 0 -> 2 -> 5 -> 1 -> 3 -> 6 ->

BFS遍历的顶点访问顺序 :5 -> 1 -> 2 -> 4 -> 6 -> 0 -> 3 ->

BFS遍历的顶点访问顺序 :6 -> 3 -> 5 -> 2 -> 1 -> 4 -> 0 ->

第3组数据输入.

请输入顶点数:

*/

原文地址:https://www.cnblogs.com/Xbingbing/p/8505276.html

时间: 2024-10-19 20:05:01

C语言实现的图的深度搜索与广度搜索程序的相关文章

图的深度遍历和广度遍历

概述 图的遍历是指从图中的任一顶点出发,对图中的所有顶点访问一次且只访问一次.图的遍历操作和树的遍历操作功能相似.图的遍历是图的一种基本操作,图的其它算法如求解图的连通性问题,拓扑排序,求关键路径等都是建立在遍历算法的基础之上. 由于图结构本身的复杂性,所以图的遍历操作也较复杂,主要表现在以下四个方面:① 在图结构中,没有一个“自然”的首结点,图中任意一个顶点都可作为第一个被访问的结点.② 在非连通图中,从一个顶点出发,只能够访问它所在的连通分量上的所有顶点,因此,还需考虑如何选取下一个出发点以

迷宫问题解决方法:分别基于深度搜索和广度搜索的思想来实现

本文针对迷宫问题,探讨解决思路并给出实现代码.在本文中,采用的图的深度优先搜索和广度优先搜索两种方法分别对迷宫的路径进行了求解. 首先来看迷宫问题的描述,可以参考此处,简而言之就是,通过一个二维数组(int型)来表示迷宫,迷宫中0表示可行,1表示不可行.在本文的实现中,可以输入给定迷宫,定义迷宫入口和出口,并查找迷宫路径. 总体的描述:在本文中,定义了结构体Node,用于存放节点信息,而Node内只有两个变量,标识节点的行坐标与列坐标.定义了迷宫类maze,并分别定义了相应的get.set函数,

深度优先搜索和广度优先搜索的深入讨论

一.深度优先搜索和广度优先搜索的深入讨论 (一)深度优先搜索的特点是: (1)从上面几个实例看出,可以用深度优先搜索的方法处理的题目是各种各样的.有的搜索深度是已知和固定的,如例题2-4,2-5,2-6:有的是未知的,如例题2-7.例题2-8:有的搜索深度是有限制的,但达到目标的深度是不定的. 但也看到,无论问题的内容和性质以及求解要求如何不同,它们的程序结构都是相同的,即都是深度优先算法(一)和深度优先算法(二)中描述的算法结构,不相同的仅仅是存储结点数据结构和产生规则以及输出要求. (2)深

深度优先搜索和广度优先搜索的比较与分(转)

深度优先搜索和广度优先搜索的深入讨论   (一)深度优先搜索的特点是: (1)无论问题的内容和性质以及求解要求如何不同,它们的程序结构都是相同的,即都是深度优先算法(一)和深度优先算法(二)中描述的算法结构,不相同的仅仅是存储结点数据结构和产生规则以及输出要求. (2)深度优先搜索法有递归以及非递归两种设计方法.一般的,当搜索深度较小.问题递归方式比较明显时,用递归方法设计好,它可以使得程序结构更简捷易懂.当搜索深度较大时,当数据量较大时,由于系统堆栈容量的限制,递归容易产生溢出,用非递归方法设

深度遍历与广度遍历

本盘文章是参考其他人的博客写的,只为自己记忆,参考者勿喷. 深度遍历:非递归,使用List保存已经访问过的节点 广度遍历:递归方式,List保存已经访问过的节点,使用Queue队列 具体图如下所示: package com.cust.grape; import java.util.ArrayList; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Que

图的深度及广度搜索

今天来学习下,图的遍历方法,我们以下面这个图为例. 开始之前呢,先说个题外话,我们用最常用的二维数组来存这个图,专业的叫法是邻接矩阵法,这好像不是题外话吧!!^_^要不要先自己想一下,上面这个图用邻接矩阵怎么存呢! 废话不多说,先来个深度的吧: 那什么叫深度搜索呢:以一个未访问过的顶点(图由顶点和边组成,不要说你不知道哦!)为起点,沿着当前顶点边走到未访问过的顶点,当没有未访问过的顶点时,回到该顶点的上一个顶点,继续走到其未访问过的顶点,直到所有顶点都被访问过.对文字不太感冒?来看下面的incl

基于C++ STL图的邻接表表示及深度、广度搜索实现

基于C++ STL图的邻接表表示及深度.广度搜索实现,对图论的学习有帮助,代码如下: #include <iostream> #include <vector> #include <set> using namespace std; #define MAX(a, b) ((a) > (b) ? (a) : (b) ) //定义图的定点 typedef struct Vertex { int id; vector<int> connectors; //存

图的遍历之 深度优先搜索和广度优先搜索

本章会先对图的深度优先搜索和广度优先搜索进行介绍,然后再给出C/C++/Java的实现. 目录 1. 深度优先搜索的图文介绍 1.1 深度优先搜索介绍 1.2 深度优先搜索图解 2. 广度优先搜索的图文介绍 2.1 广度优先搜索介绍 2.2 广度优先搜索图解 3. 搜索算法的源码 深度优先搜索的图文介绍 1. 深度优先搜索介绍 图的深度优先搜索(Depth First Search),和树的先序遍历比较类似. 它的思想:假设初始状态是图中所有顶点均未被访问,则从某个顶点v出发,首先访问该顶点,然

Java实现图的深度和广度优先遍历算法

概述: 近期要学习写网络爬虫.所以把图的深度和广度搜索都再温习一下. 图结构展示: 实现过程: 首先,我们来看看图结构在代码中的实现.有三块逻辑: 1.图中的节点: public class GraphNode { public List<GraphEdge> edgeList = null; private String label = ""; public GraphNode(String label) { this.label = label; if (edgeLis