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

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();
}

 

    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/haizi8888/article/details/8566615
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞