图的存储有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;//这里没有存储这个表示从那儿出发的,因为每个邻接表所有边的出发结点都一致。
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和队列。