这里仅仅贴出来我调试好的代码……更详细的解释在代码注释中。
#include "stdio.h"
#include "malloc.h"
#define MaxSize 10
#define MaxValue 99999
/*邻接表 :Adjacency list*/
typedef struct ArcNode //边 表节点
{
int adjvex;//邻接点 数值
ArcNode *next;//下一个节点
}ArcNode ;
typedef struct VertexNode //顶点 表节点
{
char vertex; //顶点表示(A,B,C)
ArcNode *firstedge;//第一个邻接点
}VertexNode,AdjList[MaxSize]; //为什么要写在这个地方 ????
//vertexNode AdjList[MaxSize]; //这样为什么不对??
typedef struct
{
AdjList adjlist ;//顶点表 就是竖着的一排 不能是指针么???????????? !!!!!!!!!!!
int VertexNumber,arcNum;//图的顶点个数,边个数
}AlGraph;
void CreatALGraph(AlGraph *G,char a[],int n,int e) //顶点 由数组提供, 边需要用户输入
{
int i,k,j;
G->VertexNumber=n;// 顶点个数
G->arcNum=e;//边个数
for(i=0;i<G->VertexNumber;i++)//初始化 顶点列表
{
G->adjlist[i].vertex=a[i];
G->adjlist[i].firstedge=NULL;
}
for(k=0;k<G->arcNum;++k)//每次输入 一条边 <i,j> 将该顶点插入 i 顶点后的列链表中
{
printf("please input the number of edge's two vertex\n");
scanf("%d%d",&i,&j);//有向图 f
ArcNode *s=(ArcNode *)malloc(sizeof(ArcNode));
s->adjvex=j; //所邻接的 顶点在顶点列表中的下标
//接下来 将创建好的边 表节点插入 节点i 的边表的表头
s->next=G->adjlist[i].firstedge;
G->adjlist[i].firstedge=s;
}
}
void print_Graph(AlGraph *G) //简单的打印出来
{
int i;
for(i=0;i<G->VertexNumber;++i) //输出每一行
{
ArcNode *node= G->adjlist[i].firstedge;
printf("%c",G->adjlist[i].vertex);//输出链表节点
while(node)//输出后续节点
{
//printf("--->%d", node->adjvex);
printf("--->%c", G->adjlist[1].vertex);
node=node->next;
}
printf("\n");
}
}
void DFSTraverse(AlGraph *G,int v)//深度优先遍历
{
int visited[v];//用来区别 顶点有没有被访问过
int j;
printf("%c",G->adjlist[v].vertex);//输出顶点 (递归调用 条件下文给出)
visited[v]=1;
ArcNode *p=G->adjlist[v].firstedge;
while(p!=NULL)
{
j=p->adjvex;//后继 的节点的下标
if(visited[j]!=1)//后继顶点没有被访问,则递归访问
DFSTraverse(G,j);
p=p->next;
}
}
void BFSTraverse(AlGraph *G,int v)//深度优先遍历 (递归)
{
int visited[v];//用来区别 顶点有没有被访问过
int front,rear,j;
int Q[MaxSize];
front =rear=-1;//初始化队列
printf("%c",G->adjlist[v].vertex);
visited[v]=1;
Q[++rear]=v;
while(front!=rear)
{
v=Q[++front];
ArcNode *p=G->adjlist[v].firstedge;
while(p!=NULL)
{
j=p->adjvex;//后继 的节点的下标
if(visited[j]!=1)//后继顶点没有被访问,则递归访问
{
printf("%c",G->adjlist[j].vertex);
visited[j]=1;
Q[++rear]=j;
}
p=p->next;
}
}
}
void BFS(AlGraph *G,int s) //非递归 广度优先
{
int i,u;
char color[G->VertexNumber];//表示颜色
int d[G->VertexNumber];//表示路径值
int pi[G->VertexNumber];//表示祖先
for(i=1;i<G->VertexNumber;++i)//初始化
{
color[i]='W';//初始化为白色
d[i]=MaxValue;
//pi[i]=NULL;
}
color[s]='G';//设置成灰色
d[s]=0;
//pi[s]=NULL;
int Q[MaxSize];//初始化队列
int front =-1;
int rear=-1;//初始化队列
Q[++rear]=s;//插入队列
while(front!=rear)
{
u=Q[++front];//弹出队列头
ArcNode *p=G->adjlist[u].firstedge;//这里是u
while(p!=NULL)//访问所有跟 u 相邻的节点
{
if(color[p->adjvex]=='W')//是白色 ,没有被访问过
{
color[p->adjvex]='G';
d[p->adjvex]=d[u]+1;
pi[p->adjvex]=u;
Q[++rear]=p->adjvex;//插入队列
}
p=p->next;
}
printf("%3c",G->adjlist[u].vertex);
color[u]='B';
}
}
void DFS_VISIT(AlGraph *G, int u,char color[],int d[],int f[],int time,int pi[])//被深度优先访问调用
{
color[u]='G';
++time;
d[u]=time;//第一个时间戳
ArcNode *p=G->adjlist[u].firstedge;//这里是u
while(p!=NULL)//访问所有跟 u 相邻的节点
{
if(color[p->adjvex]='W')
{
pi[p->adjvex]=u;
DFS_VISIT(G,p->adjvex,color,d,f,time,pi);
}
p=p->next;
}
color[u]='B';
printf("%3c",G->adjlist[u].vertex);
f[u]=time+1;
}
int time=0;//时间戳应该是全局变量
void DFS(AlGraph *G)//深度优先遍历
{
char color[G->VertexNumber];
int pi[G->VertexNumber];
int d[G->VertexNumber];//时间戳一
int f[G->VertexNumber];//时间戳二
int i;
for(i=0;i<G->VertexNumber;++i)//初始化
{
color[i]='W';//初始化为白色
time=0;
//pi[i]=NULL;
}
for(i=0;i<G->VertexNumber;++i)//从上到下访问
{
if(color[i]='W')
{
DFS_VISIT(G,i,color,d,f,time,pi);//深度优先访问
}
}
}
int main()
{
AlGraph *G=(AlGraph *)malloc(sizeof(AlGraph));
char a[3]={'A','B','C'};
int n=3;
int e=2;
printf("********************\n");
printf("1,创建邻接表类型的图\n");
printf("2,邻接表真实输出\n");
printf("3,邻接表深度优先访问\n");
printf("4,邻接表广度优先访问\n");
printf("5,邻接表非递归广度优先访问(算法导论)\n");
printf("6,邻接表深度优先访问(算法导论)\n");/////这个调用,有错误。需要设全局变量。没改
printf("********************\n");
int i;
while(1)
{
scanf("%d",&i);
switch(i)
{
case 1:CreatALGraph(G,a,n,e);
printf("创建完毕请继续……\n");break;
case 2:print_Graph(G);
printf("操作完毕请继续……\n");break;
case 3:DFSTraverse(G,0);
printf("操作完毕请继续……\n");break;
case 4:BFSTraverse(G,0);
printf("操作完毕请继续……\n");break;
case 5:printf("广度优先遍历:\n");
BFS(G,0);
printf("操作完毕请继续……\n");break;
case 6:DFS(G);
printf("操作完毕请继续……\n");break;
case 7:break;
case 8:break;
case 9:break;
}
}
return 0;
}
分享到:
相关推荐
本话题主要探讨如何使用非递归算法对无向图进行深度优先遍历(DFS, Depth First Search)和广度优先遍历(BFS, Breadth First Search),这两种遍历方法在图算法中有着广泛的应用。 **1. 邻接表表示法** 在处理大...
二叉树深度优先遍历、广度优先遍历{非递归}
本文将详细介绍二叉树的深度优先搜索和广度优先搜索的非递归方法实现。 深度优先搜索的非递归方法实现: 深度优先搜索是一种遍历二叉树的方式,它沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点 v 的...
深度优先搜索是一种沿着图的深度方向探索节点的方法,直到达到叶子节点或者回溯到一个未完全访问的节点。在C++中,非递归实现通常使用栈来存储待访问的节点。基本步骤包括: 1. 初始化一个栈,将根节点压入栈。 2. ...
二叉树遍历是访问树中所有节点的一种方法,通常分为三种主要策略:深度优先搜索(DFS)和广度优先搜索(BFS),以及非递归实现。在PHP中,这些遍历方法可以用来处理各种数据结构问题,例如解决问题、搜索和排序等。 ...
### 图的存储与深度优先与广度优先遍历 #### C++实现的图的存储结构 在本篇文章中,我们将探讨图数据结构的存储方法及其两种主要的遍历算法:深度优先搜索(DFS)和广度优先搜索(BFS)。图是一种非线性的数据结构...
广度优先遍历是一种非递归的遍历策略,它遵循“先进先出”(FIFO)的原则,即从源点开始逐层向外扩展,一层一层地访问图中的顶点。 **广度优先遍历的过程** 1. **初始化**: 同深度优先遍历。 2. **选择源点**: ...
[数据结构作业3]图的广度优先与深度优先分别使用递归与非递归的方式实现
我们还需要实现递归函数或循环来执行DFS和非递归函数(使用队列)来执行BFS。 在实际应用中,八数码问题不仅有助于理解搜索算法,还常被用来教授状态空间搜索、回溯法以及剪枝等概念。通过比较DFS和BFS,我们可以更...
- **非递归实现**:利用栈来保存未访问过的节点,每次从栈顶取出一个节点进行访问,并将它的邻接节点压入栈中。 ##### 3.3 应用场景 - **迷宫寻找出路**:通过深度优先搜索可以找到从起点到终点的一条路径。 - **N...
深度优先遍历是一种递归的遍历方式,从图中的一个顶点出发,尽可能深入地沿着每条路径前进,直到没有可访问的顶点为止,然后回溯到上一个节点,继续探索未访问的分支。在遍历过程中,会使用一种称为“访问标记”的...
DFS可以采用递归或非递归方式实现,通常用栈来存储待处理的状态。在八数码问题中,DFS可能找到解决方案,但不保证是最短的。由于其深入探索的特点,DFS在解决某些问题时可能比BFS更节省空间,但在寻找最短路径时效率...
深度优先遍历的实现; 广度优先遍历的实现;
在这个"数据结构之图的表示、深度优先和广度优先遍历.zip"压缩包中,我们重点探讨的是图这一重要的数据结构,以及如何通过邻接矩阵和邻接表来表示它,以及如何进行深度优先遍历(DFS)和广度优先遍历(BFS)。...
在计算机科学中,图是表示对象间关系的有效方式,而深度优先搜索(DFS)和广度优先搜索(BFS)是两种常见的图遍历算法,常用于解决各种问题,如查找连通性、最短路径等。 深度优先搜索是一种探索图的方法,它尽可能...
这是数据结构图的遍历算法,非递归,深度优先和广度优先搜索都有
图的邻接矩阵是一种常见的图表示方法,而深度优先遍历(DFS)和广度优先遍历(BFS)是两种基本的图遍历算法。接下来,我们将详细讨论这些概念。 首先,我们来看图的邻接矩阵表示。在邻接矩阵中,我们使用一个二维...
【图的非递归深度遍历以及广度遍历】是图论中的基本操作,用于探索图中的所有节点。在本实验中,我们将探讨如何使用C语言和C++实现这两种遍历方法,而不依赖递归。 首先,我们需要理解图的两种主要存储结构:**邻接...
图的遍历有两大基本方法:深度优先搜索(DFS, Depth-First Search)和广度优先搜索(BFS, Breadth-First Search)。 1. 深度优先遍历(DFS) 深度优先遍历是一种递归策略,它尽可能深入地探索图的分支。当一条路径...