图的实现和图的深度遍历 Graph's DFS

图的存储有2种方式:

1、数组形式存储的邻接矩阵法

2、链表形式存储的邻接表法。

图的遍历方法有2种方式:

1、深度优先遍历

2、广度优先遍历


一、图的存储

数组形式存储的邻接矩阵法:

这里我们申请一块矩阵大小的连续空间,然后用一个数组指针来操作二维数组,如edge[i][j]。

int (*edge)[VERTEXNUM] = (int (*)[VERTEXNUM])malloc(sizeof(int)*VERTEXNUM*VERTEXNUM);


链表形式存储的邻接表法:

1. 某个结点所能到达的结点将会组成一个单链表(称作邻接表),那么一个拥有n个结点的图将会有n个邻接表。这样一个A点所拥有的邻接表中所有的结点都意味着“从A点出发到某个点有一条边”。

我们用下面的结构来表示邻接表中的一个结点:

typedef struct edge{
int vertex;  //该边所到达的结点编号
struct edge *next;  //邻接的下一条边
}st_edge;//这里没有存储这个表示从那儿出发的,因为每个邻接表所有边的出发结点都一致。

2. 各个 单链表的首结点地址将会存在一个 连续数组中,便于访问。

st_edge** edge = (st_edge**)malloc(sizeof(st_edge*)*VERTEXNUM);

查找某个结点所拥有的邻接表,需要在edge基础上向后移动指针。*(edge+i)是图的i号点的邻接表的首结点地址。



二、图的遍历

设置一个全局数组来保存遍历情况

int *vertexStatusArr = (int*)malloc(sizeof(int)*VERTEXNUM);


邻接矩阵的DFS深度遍历:

void dfs(int (*edge)[VERTEXNUM], int* vertexStatusArr)
{
	int i;
	printf("DFS: \n");
	for(i=0;i<VERTEXNUM;i++)
		dfscore(edge, i, vertexStatusArr);
	printf("\n");
}

void dfscore(int (*edge)[VERTEXNUM], int i, int* vertexStatusArr)
{
	if(vertexStatusArr[i] == 1)
		return;
	printf("%d ", i);
	vertexStatusArr[i] = 1;

	for(int j=0;j<VERTEXNUM;j++)
		if(edge[i][j] == 1)
			dfscore(edge, j , vertexStatusArr);
}

邻接表的DFS深度遍历:

void dfs(st_edge** edge, int* vertexStatusArr)
{
	printf("DFS: ");
	int i;
	for(i=0;i<VERTEXNUM;i++)
		dfscore(edge, i, vertexStatusArr);
	printf("\n");
}

void dfscore(st_edge** edge, int i, int* vertexStatusArr)
{
	if(vertexStatusArr[i] == 1)
		return;
	printf("%d ", i);
	vertexStatusArr[i] = 1;

	st_edge* p = *(edge+i);
	while(p != NULL)
	{
		dfscore(edge, p->vertex, vertexStatusArr);
		p = p->next;
	}
}






完整代码:

//邻接矩阵的深度优先遍历
#include <stdio.h>
#include <malloc.h>
#define VERTEXNUM 5

void createGragh(int (*edge)[VERTEXNUM], int start, int end);
void display(int (*edge)[VERTEXNUM]);
void dfs(int (*edge)[VERTEXNUM], int* vertexStatusArr);
void dfscore(int (*edge)[VERTEXNUM], int i, int* vertexStatusArr);

void dfs(int (*edge)[VERTEXNUM], int* vertexStatusArr)
{
	int i;
	printf("DFS: \n");
	for(i=0;i<VERTEXNUM;i++)
		dfscore(edge, i, vertexStatusArr);
	printf("\n");
}

void dfscore(int (*edge)[VERTEXNUM], int i, int* vertexStatusArr)
{
	if(vertexStatusArr[i] == 1)
		return;
	printf("%d ", i);
	vertexStatusArr[i] = 1;

	for(int j=0;j<VERTEXNUM;j++)
		if(edge[i][j] == 1)
			dfscore(edge, j , vertexStatusArr);
}

void display(int (*edge)[VERTEXNUM])
{
	for(int i=0;i<VERTEXNUM;i++)
	{
		for(int j=0;j<VERTEXNUM;j++)
			printf("%d ", edge[i][j]);
		printf("\n");
	}
}

void createGragh(int (*edge)[VERTEXNUM], int start, int end)
{
	edge[start][end] = 1;
}


int main()
{
	int i,j;
	int (*edge)[VERTEXNUM] = (int (*)[VERTEXNUM])malloc(sizeof(int)*VERTEXNUM*VERTEXNUM);
	for(i=0;i<VERTEXNUM;i++)
		for(j=0;j<VERTEXNUM;j++)
			edge[i][j] = 0;

	int* vertexStatusArr = (int*)malloc(sizeof(int)*VERTEXNUM);
	for(i=0;i<VERTEXNUM;i++)
		vertexStatusArr[i] = 0;

	display(edge);
	createGragh(edge, 0, 3);
	createGragh(edge, 0, 4);
	createGragh(edge, 3, 1);
	createGragh(edge, 3, 2);
	createGragh(edge, 4, 1);

	display(edge);

	dfs(edge, vertexStatusArr);
	free(edge);
	return 1;
}


//邻接表矩阵的深度优先遍历
#include <stdio.h>
#include <malloc.h>
#define VERTEXNUM 5

typedef struct edge{
	int vertex;
	struct edge *next;
}st_edge;

void createGragh(st_edge** edge, int start, int end);
void display(st_edge** edge);
void delGragh(st_edge** edge);
void dfs(st_edge** edge, int* vertexStatusArr);
void dfscore(st_edge** edge, int i, int* vertexStatusArr);


void dfs(st_edge** edge, int* vertexStatusArr)
{
	printf("DFS: ");
	int i;
	for(i=0;i<VERTEXNUM;i++)
		dfscore(edge, i, vertexStatusArr);
	printf("\n");
}

void dfscore(st_edge** edge, int i, int* vertexStatusArr)
{
	if(vertexStatusArr[i] == 1)
		return;
	printf("%d ", i);
	vertexStatusArr[i] = 1;

	st_edge* p = *(edge+i);
	while(p != NULL)
	{
		dfscore(edge, p->vertex, vertexStatusArr);
		p = p->next;
	}
}

void createGragh(st_edge** edge, int start, int end)
{
	st_edge* newedge = (st_edge*)malloc(sizeof(st_edge));
	newedge->vertex = end;
	newedge->next = NULL;

	edge = edge + start;
	while(*edge != NULL)
		edge = &((*edge)->next);
	*edge = newedge;
}

void display(st_edge** edge)
{
	int i;
	st_edge* p;
	for(i=0;i<VERTEXNUM;i++)
	{
		printf("%d: ", i);
		p = *(edge+i);
		while(p!=NULL)
		{
			printf("%d ", p->vertex);
			p = p->next;
		}
		printf("\n");
	}
}

void delGragh(st_edge** edge)
{
	int i;
	st_edge* p;
	st_edge* del;
	for(i=0;i<VERTEXNUM;i++)
	{
		p = *(edge+i);
		while(p!=NULL)
		{
			del = p;
			p = p->next;
			free(del);
		}
		edge[i] = NULL;
	}
	free(edge);
}

int main()
{
	st_edge** edge = (st_edge**)malloc(sizeof(st_edge*)*VERTEXNUM);
	int i;
	for(i=0;i<VERTEXNUM;i++)
		edge[i] = NULL;
	int *vertexStatusArr = (int*)malloc(sizeof(int)*VERTEXNUM);
	for(i=0;i<VERTEXNUM;i++)
		vertexStatusArr[i] = 0;

	createGragh(edge, 0, 3);
	createGragh(edge, 0, 4);
	createGragh(edge, 3, 1);
	createGragh(edge, 3, 2);
	createGragh(edge, 4, 1);

	display(edge);
	dfs(edge, vertexStatusArr);
	edge = NULL;
	free(vertexStatusArr);
	vertexStatusArr = NULL;
	return 1;
}


下一回再总结图的BFS和队列。


你可能感兴趣的:(图的实现和图的深度遍历 Graph's DFS)