图的存储有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和队列。