`

【算法导论】图的创建,深度优先访问,广度优先访问(递归/非递归)

 
阅读更多

这里仅仅贴出来我调试好的代码……更详细的解释在代码注释中。

#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;
}

分享到:
评论

相关推荐

    算法导论中文版

    5. 图算法:深入讨论图的搜索算法(如深度优先搜索和广度优先搜索)、最短路径问题(如迪杰斯特拉算法、贝尔曼-福特算法)、最小生成树问题(如普里姆算法、克鲁斯卡尔算法)。 6. 动态数据结构:探索堆、二叉搜索...

    算法导论_(美)Cormen

    此外,《算法导论》还涵盖了各种算法,如排序(冒泡排序、选择排序、插入排序、快速排序、归并排序、堆排序等)、搜索(深度优先搜索、广度优先搜索)、图算法(Dijkstra算法、Floyd-Warshall算法、Prim算法、...

    中科大 算法导论 课件(全套11)回溯法

    ### 中科大 算法导论 课件(全套11)回溯法 #### 知识点解析 **1. 回溯法的概念与背景** - **定义**: 回溯法是一种用于解决组合优化问题的算法,它通过在解空间树中进行深度优先搜索来寻找问题的所有可能解或最...

    山东大学计算机2018年算法导论试题.

    设计DFS算法需要考虑递归实现或栈辅助的非递归实现,以及如何处理边的访问状态,确保所有边仅被访问一次。 九、最短路径的动态规划设计 动态规划是解决最短路径问题的一种高效方法,如Floyd-Warshall算法可求解所有...

    算法导论源程序c++实现

    书中包含了许多图算法的C++实现,如深度优先搜索(DFS)、广度优先搜索(BFS)、Dijkstra算法(单源最短路径)、Floyd-Warshall算法(所有对最短路径)和Prim算法(最小生成树)等。 六、字符串处理 字符串在计算机...

    算法导论影印版 第二版

    6. **图算法**:涵盖了图的遍历(深度优先搜索和广度优先搜索)、最小生成树(Prim和Kruskal算法)、最短路径(Dijkstra算法和Floyd-Warshall算法)等重要算法。 7. **字符串处理**:包括模式匹配(如KMP算法)、...

    算法导论习题解答中文版

    《算法导论》中讲解了图的表示方法(邻接矩阵和邻接表)、图的搜索算法(深度优先搜索和广度优先搜索)、最短路径算法(迪杰斯特拉算法和贝尔曼-福特算法)以及最小生成树算法(普里姆算法和克鲁斯卡尔算法)。...

    算法导论-中文版

    - 深度优先搜索:在图中探索尽可能深的节点。 - 广度优先搜索:从根节点开始,一层层遍历所有节点。 **知识点四:高级算法概念** - **动态规划**: - 一种通过把原问题分解为互相重叠的子问题的方式求解复杂...

    算法导论第六章习题解答

    《算法导论》第六章主要涉及图算法,包括图的基本概念、图的表示方法、图的遍历(深度优先搜索DFS和广度优先搜索BFS)、最短路径问题(Dijkstra算法、Floyd-Warshall算法)、最小生成树(Prim算法、Kruskal算法)...

    算法导论第十六章习题解答

    2. **深度优先搜索(DFS)与广度优先搜索(BFS)** 这两种搜索策略是解决图问题的核心工具。DFS适用于发现图的深层次结构,而BFS则用于找到最近的邻居。在解题中,我们通常会用递归或栈实现DFS,用队列实现BFS。 ...

    三份 <算法导论> 英文版答案

    - 图:邻接矩阵和邻接表表示,深度优先搜索(DFS)和广度优先搜索(BFS),最小生成树算法(Prim和Kruskal)和最短路径算法(Dijkstra和Floyd-Warshall)。 3. **排序与搜索算法**: - 冒泡排序、插入排序、选择...

    《算法导论》答案

    2. **搜索算法**:如二分查找、广度优先搜索(BFS)和深度优先搜索(DFS)。了解它们在数组和图结构中的应用。 3. **图算法**:如Dijkstra最短路径算法、Floyd-Warshall算法、Prim最小生成树算法和Kruskal最小生成...

    算法导论教师手册

    - **主题介绍**:学习深度优先搜索(DFS)和广度优先搜索(BFS)两种图的遍历算法。 - **关键术语**:深度优先搜索、广度优先搜索。 - **案例分析**:演示如何使用DFS和BFS遍历一个无向图。 #### 第二十三章:最小...

    算法导论 part1

    根据提供的文件信息,我们可以推断出此文档与“算法导论”有关,但具体到第一部分的内容并未直接给出。为了生成相关知识点,我们将基于“算法导论”这一主题进行展开,探讨该领域的基础概念和技术要点。 ### 算法...

    MIT_Introduction to Algorithms 算法导论视频字幕

    29 第十七课 最短路径,Dijkstra算法,广度优先搜寻法 阅读:22 章1, 2 节;第 580 - 587 页,24章 3 节 收《作业 8》发《作业 9》 30 演示课 11 深度优先搜寻法,边的分类 阅读:22 章 3 到 5 节 31 第十八课 ...

    MIT 算法导论第二版

    总之,《MIT算法导论第二版》是一部集深度与广度于一体的计算机算法学习宝典,无论是对于初学者还是有经验的开发者,都是一本不可多得的学习资源。通过阅读本书,读者不仅能学到各种算法的设计与分析技巧,还能培养...

    麻省理工学院.算法导论

    2. **Lecture 05**: 可能讲解了图算法,包括图的表示、DFS(深度优先搜索)和BFS(广度优先搜索)等。 3. **Lecture 06**: 可能深入到动态规划,解释了如何利用递归和记忆化技术解决复杂问题,如背包问题、最短路径...

    英文版算法导论和答案

    3. **图算法**:书中详细阐述了图的表示方法(邻接矩阵和邻接表),并介绍了DFS(深度优先搜索)、BFS(广度优先搜索)以及Dijkstra、Floyd-Warshall等最短路径算法,还有Prim和Kruskal的最小生成树算法,这些都是...

Global site tag (gtag.js) - Google Analytics