資料結構,資料結構c語言版
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); #endifprintf("輸入頂點:\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;}