数据结构:图深度优先遍历算法

来源:互联网 发布:c语言判断奇偶 编辑:程序博客网 时间:2024/06/06 01:48

1:基本概念:

       图:图G是由两个集合V (G)和E(G)所组成,记为G=(V,E);其中V (G)是图顶点的非空有限集合,E(G)是图中边的有限集合。

       有向图:V(G1)={v1,v2,v3};

                       E(G1)={<V1,V2>,<V2,V1>,<V2,V2>}

       无向图:V(G2)={v1,v2,v3,v4};

                       E(G2)={(V1,V2),(V1,V3),(V1,V4),(v2,v3),(v2,v4),(v3,v4)}


2:图的存储结构:

对于如下的有向图:


(1)邻接矩阵:使用一个二维数组的方法,对于存在的边(u,v),我们置A[u][v]=1,否则为0;优点是非常简单,但是空间需求则为@(|V|^2),(|V|为顶点的个数),如果图是稠密的话,那么这种表示还算合理,但往往情况并非如此。

(2)邻接表:建立一张表,表的表头分别为每个顶点,那么空间需求为O(|E|+|V|)。(边的个数+顶点个数)。对于稀疏表,这个应用相当广泛。下图是其表示方法:


    顺便提下,在实际应用中,顶点都是有名字的而非单纯的数字。那么我们应该联想到散列表,所以要结合散列表应用。


(3) 遍历:深度优先遍历。

针对以下无向图,写出深度优先遍历


首先,我们从A点开始。此时,标记A为访问过的并递归调用Dfs(B)。Dfs(B)标记B为访问过的并递归调用Dfs(C)。Dfs(C)标记C为访问过的并递归调用Dfs(D)。 Dfs(D)标记D为访问过的并发现ABC均是访问过的节点,那么返回到Dfs(C),Dfs(C)看到B没有标记,那么递归调用Dfs(E)。那么递归调用Dfs(E)。

递归调用Dfs(E)标记E为访问过的顶点,也发现ABC均为访问过的顶点,那么返回Dfs(C),再依次返回Dfs(B),Dfs(A)。

因为采用邻接表的方法,用Visited[]来标记是否被访问过,我们知道只要消耗O(V)的时间就能遍历所有的节点,每个顶点操作的总的时间消耗需要O(e)的时间,所以说此算法总共需要O(e+V)的时间。


C代码如下所示:

#include <stdio.h>#include <stdlib.h>#define Max_VerTex 6//最大的顶点数//为什么会有node和vnode呢,它们貌似是可以合并的,但是对于后面的//代码的编写,会发现分开后代码容易写typedef struct node{int value;//每个顶点的位置(即1,2,3,4,5,6...)struct node *next;//每个节点指向下一个节点}node;typedef struct vnode{int info;//一张邻接表的 表头的信息 在这个 程序中没有必要存在node *firstnode;//表示表头连接的第一个节点}vnode;typedef struct graph{vnode table[Max_VerTex];//生成一张邻接表int vertex_num;int edge_num;//边和顶点数}graph;static int visited[Max_VerTex];static graph *gp;//建立连接表void initial(){int i= 0;int index;int point_value;node *newnode;node *temp_node;int g_array[12][2]={{1,2},{1,3},{2,1},{2,4},{2,5},{4,2},{4,6},{6,4},{6,5},{5,2},{5,6},{3,1}};//基本的初始化操作gp = (graph *)malloc(sizeof(graph));gp->vertex_num = 6;gp->edge_num = 12;for(;i<gp->vertex_num;i++){gp->table[i].firstnode = (node *)malloc(sizeof(node));gp->table[i].firstnode->value = i+1;gp->table[i].firstnode->next = NULL;}//建立邻接表的关键部分for(i=0;i<gp->edge_num;i++){index = g_array[i][0]-1;point_value = g_array[i][1];newnode = (node *)malloc(sizeof(node));newnode->value = point_value;newnode->next=NULL;temp_node = gp->table[index].firstnode;while(temp_node->next != NULL){temp_node = temp_node->next;}temp_node->next=newnode;}return;}void DFSTraverse(int i){node *temp_node;visited[i]=1;printf("%d ",i+1);temp_node=gp->table[i].firstnode->next;while(temp_node != NULL){if(visited[temp_node->value-1]==0){DFSTraverse(temp_node->value-1);}temp_node=temp_node->next;}return;}void Dfs(){int i;for(i=0;i<gp->vertex_num;i++){visited[i]=0;}i=0;//for(i=0;i<gp->vertex_num;i++){//此条语句是用于非单连通的图使用的if(visited[i]==0){DFSTraverse(i);}//}}void main(){initial();Dfs();}


 

原创粉丝点击