基于图(graph)的应用举例
2013-03-03 18:11
337 查看
1、统计网络跳数
图在解决许多与网络相关的问题时起到了重要的作用,统计在internet中从一个节点访问其他节点时中间必须经过的最小的节点数,这个消息在internet中非常有用,因为最明显的网络开销直接和所要的遍历的节点数目相关。
下面是采用BFS实现计算网络跳数,使用了前面提供的队列及链表的函数接口。在阅读中希望先把链表和队列的相关的函数接口了解下。
先了解下程序中几个结构体之间关系:(在写拓扑排序的时候,脑子一下子就乱了,不知道几个结构体之间的关系,特别绘制了下面的图,希望能对大家的理解有帮助)。
![](http://img.my.csdn.net/uploads/201303/05/1362484623_4082.jpg)
/*bfs.h *下面是关于图在网络跳数中的应用 *采用广度优先的搜索方法 * */ #ifndef BFS_H #define BFS_H #include "graph.h" #include "list.h" /*定义顶点的结构体体,在广度优先搜索*/ typedef struct BfsVertex_ { void *data;//指向图中顶点的数据的指针 VertexColor color;//在搜索过程中维护顶点的颜色 int hops;//维护从起始到顶点的跳数统计 }BfsVertex; /*函数接口*/ int bfs(Graph *graph,BfsVertex *start,List *hops); #endif
/*bfs.c*/ #include <stdlib.h> #include "../include/bfs.h" #include "../include/graph.h" #include "../include/list.h" #include "../include/queue.h" /*********************************************** *广度优先搜索方法实现网络中两个节点之间的跳数 *参数:graph:代表整个网络 * start:代表起始的顶点 * hops:返回的跳数链表 *返回值:成功返回0,失败-1 * *************************************************/ int bfs(Graph *graph,BfsVertex *start,List *hops) { Queue queue; Adjlist *adjlist, *clr_adjlist; BfsVertex *clr_vertex, *adj_verex; ListElmt *element, *member; /*初始化图中所有的节点 *当节点是起始节点vstart时,初始化成黑色,跳数为0; *其他初始化位白色,跳数为-1. * */ for (element = list_head(graph->adjlists);element != NULL;element = list_next(element)){ clr_vertex = ((Adjlist *)list_data(element))->vertex; if (graph->match(clr_vertex,start)){ clr_vertex->color = gray; clr_vertex->hops = 0; } else { clr_vertex->color = gray; clr_vertex->hops = 0; } } /*初始化队列*/ queue_init(&queue,NULL); /*获得开始顶点的结构体,并加入到队列中*/ if (graph_adjlit(graph,start,&clr_adjlist) != 0){ queue_destroy(&queue); return -1; } if (queue_enqueue(&queue,clr_adjlist) != 0){ queue_destroy(&queue); return -1; } /*BFS*/ while (queue_size(&queue) > 0){ /*得到队列中的首个节点元素*/ adjlist = queue_peek(&queue); /*以此获得当前顶点的邻接顶点,并着色,和设置跳数*/ for (member = list_head(&adjlist->adjacent);member != NULL; member = list_next(member)){ /*获得顶点*/ adj_verex = list_data(member); /*获得当前顶点的adjlist结构体*/ if (graph_adjlit(graph,adj_verex,&clr_adjlist) != 0){ queue_destroy(&queue); return -1; } clr_vertex = clr_adjlist -> vertex; /*设定顶点的颜色及跳数*/ if (clr_vertex ->color == while ){ clr_vertex -> color = gray; clr_vertex -> hops = ((BfsVertex *)adjlist -> vertex)->hops + 1; /*将当前顶点的adjlist 结构体加入队列*/ if (queue_enqueue (&queue,clr_adjlist) != 0){ queue_destroy(&queue); return -1; } } } /*在队列中将首个元素删除*/ if (queue_dequeue (&queue, (void **)&adjlist) == 0) ((BfsVertex *)adjlist->vertex)->color = black; else { queue_destroy (&queue); return -1; } } /*以上已经将图的所有节点的跳数都已经加载上*/ queue_destroy(&queue); /*下面室将所有跳数不为-1的顶点,保存到链表hops中*/ list_init(hops,NULL); for (member = list_head(&adjlist->adjacent);member != NULL; member = list_next(member)){ clr_vertex = ((Adjlist *)list_data(element)) -> vertex; if (clr_vertex->hops != -1 ){ if (list_ins_next(hops,list_tail(hops),clr_vertex) != 0){ list_destroy(hops); return -1; } } } return 0; }
2 拓扑排序
将有向无环图中的顶点按照现行的方式排列,使得所有的边都是从左向右的方式,拓扑排序的最通常的用途是在执行若干个互相之间有依赖关系的任务时,确定一种可接受的先后顺序。先看下面这个图:
![](http://img.my.csdn.net/uploads/201303/05/1362485074_8890.jpg)
/*dfs.h *下面是关于图在拓扑排序中应用 *采用深度优先的搜索方法 * */ #ifndef DFS_H #define DFS_H #include "graph.h" #include "list.h" /*定义顶点的结构体体,在广度优先搜索*/ typedef struct DfsVertex_ { void *data;//指向图中顶点的数据的指针 VertexColor color;//在搜索过程中维护顶点的颜色 }DfsVertex; /*函数接口*/ int dfs(Graph *graph,List *ordered); #endif
/*dfs*/ #include <stdlib.h> #include "../include/dfs.h" #include "../include/graph.h" #include "../include/list.h" static int dfs_main(Graph *graph, Adjlist *adjlist, List *ordered) { Adjlist *clr_adjlist; DfsVertex *clr_vertex, *adj_vertex; ListElmt *member; /*顶点着色*/ ((DfsVertex *)adjlist->vertex) -> color = gray; for (member = list_head(&adjlist->adjacent); member != NULL; member = list_next(member)){ /**/ adj_vertex = list_data(member); if (graph_adjlist(graph,adj_vertex,&clr_adjlist) != 0) return -1; clr_vertex = clr_adjlist->vertex; if (clr_vertex->color == white){ if (dfs_main(graph,clr_adjlist,ordered) != 0) return -1; } ((DfsVertex *)adj_vertex->vertex) ->color = black; if (list_ins_next(ordered,NULL,(DfsVertex *)adjlist->vertex) != 0) return -1; return 0; } /******************************************************* *参数:graph -> 图 * ordered -> 保存完成拓扑排序后返回的顶点列表 * 函数成功返回0,失败-1; * ********************************************************/ int dfs(Graph *graph,List *ordered) { DfsVertex *vertex; ListElmt *element; /*初始化图中所有的顶点*/ for (element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element)){ vertex = list_data(element); vertex ->color = white; } /*初始化链表*/ list_init(ordered,NULL); for (element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element)){ vertex = ((Adjlist *)list_data(element))->vertex; if (vertex ->color == white){ if(dfs_main(graph,(Adjlist *)list_data(element),ordered) != 0){ list_destroy(ordered); return -1; } } } return 0; }
相关文章推荐
- 基于遍历的几种二叉树运算的实现和应用举例
- 人工智能 基于遗传算法的随机优化搜索的应用举例
- 二叉树路径应用举例(基于非递归后序遍历)
- 基于javascript的拼音字典及应用举例
- 基于Lotus Notes 8 的银行业复合应用举例
- 基于Microsoft Graph打造自己的Timeline应用
- 新手上路(一):基于android平台的投票应用的开发(三)之问题整理
- heX——基于 HTML5 和 Node.JS 开发桌面应用
- SQL Server 2008空间数据应用系列八:基于Bing Maps(Silverlight)的空间数据存储
- Intel和Sun合作 提供基于Java的强大应用
- 基于mkCDrec的linux服务器数据库应用软件的备份与恢复
- 【翻译】优化基于ExtJS 4.1的应用
- 基于Eclipse的Hadoop应用开发环境配置
- Android APP安装后不在桌面显示图标的应用场景举例和实现方法
- 基于Spring的第一个小应用
- 发力于以太坊商业应用开发,他们提供基于以太坊区块链技术的行业解决方案和咨询服务
- 基于Redis的分布式锁的简单应用
- 价值100W的经验分享: 基于JSPatch的iOS应用线上Bug的即时修复方案,附源码.
- 基于 Quartz 开发企业级任务调度应用
- 基于Visual C++2010与windows SDK fo windows7开发windows7平台的tabletpc应用(1)-手写数学公式输入