数据结构--------图的遍历算法及实现
来源:互联网 发布:java ee看源代码 编辑:程序博客网 时间:2024/06/07 06:12
经过俩天的学习,现在终于明白了图的遍历算法。图的遍历是指从图中的任一顶点出发,对图中的所有顶点访问且只访问一次的过程。图的遍历是图的一种基本操作,图的其他算法如求解图的拓扑排序、关键路径等都是在遍历算法的基础上实现的。因此弄清楚图的遍历算法极其关键。
由于图结构本身的复杂性,所以图的遍历操作也较复杂,主要表现在以下四个方面:
① 在图结构中,没有一个“自然”的首结点,图中任意一个顶点都可作为第一个被访问的结点。
② 在非连通图中,从一个顶点出发,只能够访问它所在的连通分量上的所有顶点,因此,还需考虑如何选取下一个出发点以访问图中其余的连通分量。
③ 在图结构中,如果有回路存在,那么一个顶点被访问之后,有可能沿回路又回到该顶点。
④ 在图结构中,一个顶点可以和其它多个顶点相连,当这样的顶点访问过后,存在如何选取下一个要访问的顶点的问题。
图的遍历通常有深度优先搜索和广度优先搜索两种方式,他们对无向图和有向图都适用。
1、深度优先遍历递归算法
(1)首先访问节点K,如果节点K未被访问,则标记visited[k]=1并输出节点k的数据信息;
(2)查找与节点k相连的下一个节点i,如果存在且未被访问,则递归调用;接着查找与节点k相连且与节点i相邻的节点,更新i的值,直到与k相连的节点查找完毕。
2、广度优先遍历(利用队列)算法
假设从图中某顶点v 出发,在访问了v 之后依次访问v 的各个未曾访问过和邻接点,然后分别从这些邻接点出发依次访问它们的邻接点,并使“先被访问的顶点的邻接点”先于“后被访问的顶点的邻接点”被访问,直至图中所有已被访问的顶点的邻接点都被访问到。若此时图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。换句话说,广度优先搜索遍历图的过程中以v 为起始点,由近至远,依次访问和v 有路径相通且路径长度为1,2,…的顶点。
/*无向图的邻接矩阵表示*/#include<stdlib.h>#include<stdio.h>#include<malloc.h>#define MAX_VERX 20 /*最大节点数*/#define INFINITY 32767#define DataType charint *visited=NULL;struct _node /* 定义队列节点 */{int v_num;struct _node *next;};typedef struct _node node,*pnode;struct _queue /*队列数据结构*/{pnode front;pnode rear;}; typedef struct _queue queue,*pqueue;struct _graph /*图的数据结构*/{DataType *vexs;int arcs[MAX_VERX][MAX_VERX];int vexnum;int arcnum;};typedef struct _graph graph,*pgraph;/*队列的操作*/queue Init_Queue() /*队列初始化*/{queue qu;qu.front=qu.rear=(pnode)malloc(sizeof(node));if(qu.front==NULL)exit(1);qu.rear->next=NULL;return qu;}int isempty_queue(pqueue pqu) /*判断队列是否为空*/{if(pqu->front==pqu->rear)return 1;elsereturn 0;}void en_queue(pqueue pqu,int v_num) /*进队列*/{pnode pn;pn=(pnode)malloc(sizeof(node));if(pqu->front==NULL)exit(1);pn->v_num=v_num;pn->next=NULL;pqu->rear->next=pn;pqu->rear=pqu->rear->next;}int de_queue(pqueue pqu) /*出队列*/{pnode pn;int d;if(isempty_queue(pqu))return -1;pn=pqu->front; d=pn->next->v_num; //出队列时要找到队列顶部的下一节点pqu->front=pqu->front->next;free(pn);return d;}int islocate(pgraph pg,DataType ch){DataType *dt;int i;dt=pg->vexs;for(i=0;i<pg->vexnum;i++){if(ch==dt[i])return i;}return -1;}//图的基本操作graph create_graph(){int i,j,s1,s2;float w;char ch1,ch2,temp;graph g;printf("请输入顶点数和边数:");scanf("%d %d",&g.vexnum,&g.arcnum);temp=getchar();printf("请输入%d顶点信息\n",g.vexnum);g.vexs=(DataType*)malloc(g.vexnum*sizeof(DataType));for(i=0;i<g.vexnum;i++){//printf("vex[%d]: ",i);scanf("%c",&g.vexs[i]);temp=getchar();}/*for(i=0;i<g.vexnum;i++) //检查输入定点信息是否正确{printf("vex[%d]: %c\n",i,g.vexs[i]);}*/for(i=0;i<g.vexnum;i++) //初始化边值信息for(j=0;j<g.vexnum;j++){g.arcs[i][j]=INFINITY;}printf("请输入%d条边\n",g.arcnum);for(i=0;i<g.arcnum;i++){printf("请输入边%d的信息(俩边顶点权值)",i);scanf("%c %c %f",&ch1,&ch2,&w);temp=getchar();s1=islocate(&g,ch1);s2=islocate(&g,ch2);g.arcs[s1][s2]=g.arcs[s2][s1]=w;}return g;}/* 查找与顶点k相连的第一个顶点*/int firstvex_graph(graph g,int k){int j;if(k>=0&&k<g.vexnum){for(j=0;j<g.vexnum;j++){if(g.arcs[k][j]!=INFINITY)return j;}}return -1; //查找失败}/*查找与顶点i相连且在顶点j下一个的顶点*/int nextvex_graph(graph g,int i,int j){int k;if(i>=0&&i<g.vexnum&&j>=0&&j<g.vexnum){for(k=j+1;k<g.vexnum;k++){if(g.arcs[i][k]!=INFINITY)return k;}}return -1;//查找相邻节点失败}/*从顶点k开始深度优先遍历图*/void dfs(graph g,int k){int i;if(k==-1){for(i=0;i<g.vexnum;i++){if(!visited[i])dfs(g,i);}}else{ visited[k]=1;printf("%c ",g.vexs[k]);for(i=firstvex_graph(g,k);i>=0;i=nextvex_graph(g,k,i))if(!visited[i]){dfs(g,i);}}}/* 从顶点k开始广度优先遍历图 */void bfs(graph g){int i,j,k;queue qu=Init_Queue();for(i=0;i<g.vexnum;i++){if(!visited[i]){visited[i]=1;printf("%c",g.vexs[i]);en_queue(&qu,i);while(!isempty_queue(&qu)){k=de_queue(&qu);for(j=firstvex_graph(g,k);j>=0;j=nextvex_graph(g,k,j)){if(!visited[j]){visited[j]=1;printf("%c",g.vexs[j]);en_queue(&qu,j);}}}}}}int main(){int i,k=-1;graph g=create_graph();visited=(int*)malloc(g.vexnum*sizeof(int));if(visited==NULL){printf("错误!!!!!!!!!!!");}for(i=0;i<g.vexnum;i++){visited[i]=0;}printf("\n\n*******************d f s***************\n");dfs(g,k);for(i=0;i<g.vexnum;i++){visited[i]=0;}printf("\n*******************b f s***************\n");bfs(g);return 1;}
- 数据结构--------图的遍历算法及实现
- 图的数据结构及遍历算法
- 数据结构:图相关概念及遍历算法
- 数据结构_7:图算法 :图的遍历
- 【数据结构与算法】图的遍历
- [数据结构与算法]图的遍历
- 数据结构与算法--图的遍历
- 算法与数据结构--图的实现、基本操作及应用
- 数据结构----二叉树遍历的非递归算法实现
- 数据结构实践——图遍历算法实现
- 数据结构第十一周项目3--图遍历算法实现
- 数据结构和算法之:图的深度优先和广度优先遍历及其Java实现
- 数据结构第十一周项目(三)——图遍历算法的实现
- 【数据结构与算法】图 遍历
- 数据结构与算法学习记录--二叉树的创建,递归遍历,非递归遍历的实现
- Java数据结构 遍历 排序 查找 算法实现
- 算法与数据结构基础4:C++二叉树实现及遍历方法大全
- 关于图的邻接表存储建立方式及深度遍历的个人理解以及数据结构7.22的算法
- Windows中的管道解析
- Dijkstra算法求最短距离
- OpenCms 9.5.1 Container嵌套关系和配置
- 波兰表达式和逆波兰表达式
- 新域名正在备案,静候佳音
- 数据结构--------图的遍历算法及实现
- 5.1.1 Binary Tree Level Order Traversal
- SAT阅读假设题解题思路指导:理解与推理
- Java基础复习之一:static关键字的使用
- JavaScript-给iframe里的内容定义样式 获取元素
- Node.js Express框架
- iOS 调试
- java List Map数据对比 找出相同和不同的内容
- Memcached中的一些参数限制