1、邻接矩阵表示的图结构
/* 邻接矩阵表示的图结构 */ #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <queue> #include <stack> using namespace std; typedef char VertexType; //顶点类型应由用户定义 typedef int EdgeType; //边上的权值类型应由用户定义 #define MAXVEX 100 //最大顶点数,应由用户定义 #define INF 0 //用0来代表不存在该边 #define DEBUG typedef struct { VertexType vexs[MAXVEX]; //顶点表 EdgeType arc[MAXVEX][MAXVEX]; //邻接矩阵,可看作边 int numVertexes, numEdges; //图中当前的顶点数和边数 }Graph; //定位 int locates(Graph *g, char ch) { int i = 0; for(i = 0; i < g->numVertexes; i++) { if(g->vexs[i] == ch) { return i; } } if(i >= g->numVertexes) { return -1; } } //建立一个无向网图的邻接矩阵表示 void CreateGraph(Graph *g) { int i, j, k, w; printf("输入顶点数和边数:\n"); scanf("%d %d", &(g->numVertexes), &(g->numEdges)); #ifdef DEBUG printf("%d %d\n", g->numVertexes, g->numEdges); #endif printf("输入顶点:\n"); for(i = 0; i < g->numVertexes; i++) { g->vexs[i] = getchar(); while(g->vexs[i] == '\n') { g->vexs[i] = getchar(); } } #ifdef DEBUG for(i = 0; i < g->numVertexes; i++) { printf("%c ", g->vexs[i]); } printf("\n"); #endif for(i = 0; i < g->numVertexes; i++) { for(j = 0; j < g->numVertexes; j++) { g->arc[i][j] = INF; //邻接矩阵初始化 } } for(k = 0; k < g->numEdges; k++) { char p, q; printf("输入边(vi,vj)上的下标i,下标j和权值:\n"); p = getchar(); while(p == '\n') { p = getchar(); } q = getchar(); while(q == '\n') { q = getchar(); } scanf("%d", &w); int m = -1; int n = -1; m = locates(g, p); n = locates(g, q); if(n == -1 || m == -1) { fprintf(stderr, "there is no this vertex.\n"); return; } //getchar(); g->arc[m][n] = w; g->arc[n][m] = g->arc[m][n]; //因为是无向图,矩阵对称 } } //打印图 void printGraph(Graph g) { int i, j; for(i = 0; i < g.numVertexes; i++) { for(j = 0; j < g.numVertexes; j++) { printf("%6d ", g.arc[i][j]); } printf("\n"); } } #define MAXVEX 100 //最大顶点数 bool visited[MAXVEX]; //访问标志数组 #define TRUE 1 #define FALSE 0 //邻接矩阵的深度优先递归算法 void DFS(Graph g, int i) { int j; visited[i] = TRUE; printf("%c ", g.vexs[i]); //打印顶点,也可以其他操作 for(j = 0; j < g.numVertexes; j++) { if(g.arc[i][j]!=0 && !visited[j]) { DFS(g, j); //对为访问的邻接顶点递归调用 } } } //邻接矩阵的深度遍历操作 void DFSTraverse(Graph g) { int i; for(i = 0; i < g.numVertexes; i++) { visited[i] = FALSE; //初始化所有顶点状态都是未访问过状态 } for(i = 0; i < g.numVertexes; i++) { if(!visited[i]) //对未访问的顶点调用DFS,若是连通图,只会执行一次 { DFS(g,i); } } printf("\n"); } //邻接矩阵的广度遍历算法 void BFSTraverse(Graph g) { int i, j; queue<int> q; for(i = 0; i < g.numVertexes; i++) { visited[i] = FALSE; } for(i = 0; i < g.numVertexes; i++)//对每个顶点做循环 { if(!visited[i]) //若是未访问过 { visited[i] = TRUE; printf("%c ", g.vexs[i]); //打印结点,也可以其他操作 q.push(i); //将此结点入队列 while(!q.empty()) { int m = q.front(); q.pop(); for(j = 0; j < g.numVertexes; j++) { //判断其他顶点若与当前顶点存在边且未访问过 if(g.arc[m][j] != 0 && !visited[j]) { visited[j] = TRUE; printf("%c ", g.vexs[j]); q.push(j); } } } } } printf("\n"); } int main(int argc, char **argv) { Graph g; //邻接矩阵创建图 CreateGraph(&g); printGraph(g); DFSTraverse(g); BFSTraverse(g); return 0; }
2、邻接表表示的图结构
/* 邻接表表示的图结构 */ #include <cstdio> #include <cstdlib> #include <cstdlib> #include <cmath> #include <queue> #include <stack> using namespace std; #define MAXVEX 100 //最大顶点数 bool visited[MAXVEX]; //访问标志数组 #define TRUE 1 #define FALSE 0 #define DEBUG #define MAXVEX 1000 //最大顶点数 typedef char VertexType; //顶点类型应由用户定义 typedef int EdgeType; //边上的权值类型应由用户定义 typedef struct EdgeNode //边表结点 { int adjvex; //邻接点域,存储该顶点对应的下标 EdgeType weigth; //用于存储权值,对于非网图可以不需要 struct EdgeNode *next; //链域,指向下一个邻接点 }EdgeNode; typedef struct VertexNode //顶点表结构 { VertexType data; //顶点域,存储顶点信息 EdgeNode *firstedge; //边表头指针 }VertexNode, AdjList[MAXVEX]; typedef struct { AdjList adjList; int numVertexes, numEdges; //图中当前顶点数和边数 }GraphList; int Locate(GraphList *g, char ch) { int i; for(i = 0; i < MAXVEX; i++) { if(ch == g->adjList[i].data) { break; } } if(i >= MAXVEX) { fprintf(stderr,"there is no vertex.\n"); return -1; } return i; } //建立图的邻接表结构 void CreateGraph(GraphList *g) { int i, j, k; EdgeNode *e; EdgeNode *f; printf("输入顶点数和边数:\n"); scanf("%d %d", &g->numVertexes, &g->numEdges); #ifdef DEBUG printf("%d %d\n", g->numVertexes, g->numEdges); #endif for(i = 0; i < g->numVertexes; i++) { printf("请输入顶点%d:\n", i); g->adjList[i].data = getchar(); //输入顶点信息 g->adjList[i].firstedge = NULL; //将边表置为空表 while(g->adjList[i].data == '\n') { g->adjList[i].data = getchar(); } } //建立边表 for(k = 0; k < g->numEdges; k++) { printf("输入边(vi,vj)上的顶点序号:\n"); char p, q; p = getchar(); while(p == '\n') { p = getchar(); } q = getchar(); while(q == '\n') { q = getchar(); } int m, n; m = Locate(g, p); n = Locate(g, q); if(m == -1 || n == -1) { return; } #ifdef DEBUG printf("p = %c\n", p); printf("q = %c\n", q); printf("m = %d\n", m); printf("n = %d\n", n); #endif //向内存申请空间,生成边表结点 e = (EdgeNode *)malloc(sizeof(EdgeNode)); if(e == NULL) { fprintf(stderr, "malloc() error.\n"); return; } //邻接序号为j e->adjvex = n; //将e指针指向当前顶点指向的结构 e->next = g->adjList[m].firstedge; //将当前顶点的指针指向e g->adjList[m].firstedge = e; f = (EdgeNode *)malloc(sizeof(EdgeNode)); if(f == NULL) { fprintf(stderr, "malloc() error.\n"); return; } f->adjvex = m; f->next = g->adjList[n].firstedge; g->adjList[n].firstedge = f; } } void printGraph(GraphList *g) { int i = 0; #ifdef DEBUG printf("printGraph() start.\n"); #endif while(g->adjList[i].firstedge != NULL && i < MAXVEX) { printf("顶点:%c ", g->adjList[i].data); EdgeNode *e = NULL; e = g->adjList[i].firstedge; while(e != NULL) { printf("%d ", e->adjvex); e = e->next; } i++; printf("\n"); } } //邻接表的深度递归算法 void DFS(GraphList g, int i) { EdgeNode *p; visited[i] = TRUE; printf("%c ", g.adjList[i].data); //打印顶点,也可以其他操作 p = g.adjList[i].firstedge; while(p) { if(!visited[p->adjvex]) { DFS(g, p->adjvex); //对访问的邻接顶点递归调用 } p = p->next; } } //邻接表的深度遍历操作 void DFSTraverse(GraphList g) { int i; for(i = 0; i < g.numVertexes; i++) { visited[i] = FALSE; } for(i = 0; i < g.numVertexes; i++) { if(!visited[i]) { DFS(g, i); } } printf("\n"); } //邻接表的广度遍历算法 void BFSTraverse(GraphList g) { int i; EdgeNode *p; queue<int> q; for(i = 0; i < g.numVertexes; i++) { visited[i] = FALSE; } for(i = 0; i < g.numVertexes; i++) { if(!visited[i]) { visited[i] = TRUE; printf("%c ", g.adjList[i].data); //打印顶点,也可以其他操作 q.push(i); while(!q.empty()) { int m; m = q.front(); q.pop(); p = g.adjList[m].firstedge; // 找到当前顶点边表链表头指针 while(p) { if(!visited[p->adjvex]) { visited[p->adjvex] = TRUE; printf("%c ", g.adjList[p->adjvex].data); q.push(p->adjvex); } p = p->next; } } } } printf("\n"); } int main(int argc, char **argv) { GraphList g; CreateGraph(&g); printGraph(&g); DFSTraverse(g); BFSTraverse(g); return 0; }
时间: 2024-10-08 11:18:26