圖主要分為無向圖、有向圖和網。存儲方式主要是鄰接矩陣和鄰接表,接下來我寫的是數據結構無向圖鄰接矩陣的構建方法
1.結構體
#define MAX 20 //邊和頂點的最大數量 typedef char ElemType; typedef struct Graph{ int vexNum; //頂點數 int arcNum; //邊的數量 ElemType vexs[MAX]; //頂點信息 int arcs[MAX][MAX]; //邊的信息 }Graph,*myGraph;
2.構建圖
void createGraph(myGraph &G) { G=(Graph*)malloc(sizeof(Graph)); //結構體的指針要初始化 int i,j,k; int vexNum,arcNum; char v1,v2; //邊的兩個頂點 printf("請輸入頂點的數量:"); scanf("%d",&G->vexNum); printf("請輸入邊的數量:"); scanf("%d",&G->arcNum); printf("請依次將頂點數據輸入進來\n"); for(i=0;i<G->vexNum;i++) { getchar(); scanf("%c",&G->vexs[i]); } for(i=0;i<G->vexNum;i++) { for(j=0;j<G->vexNum;j++) { G->arcs[i][j]=0;//初始化矩陣 } } printf("請依次將邊輸入進來\n"); for(i=0;i<G->arcNum;i++) { getchar(); scanf("%c%c",&v1,&v2); j=getLocate(G,v1); k=getLocate(G,v2); G->arcs[j][k]=1; G->arcs[k][j]=1; } }
3.輸出鄰接矩陣
void printfGraph(myGraph G) { int i,j; printf(" "); for(i=0;i<G->vexNum;i++) { printf("%c ",G->vexs[i]); } printf("\n"); for(i=0;i<G->vexNum;i++) { printf("%c ",G->vexs[i]); for(int j=0;j<G->vexNum;j++) { printf("%d ",G->arcs[i][j]); } printf("\n"); } }
4.圖的深度優先遍歷
深度優先遍歷:先遍歷第一元素頂點,在遍歷該頂點最近的鄰接點,如此反復循環,如果無法找到鄰接點,則返回回來
void DFS(myGraph G,int i,int *visit) { int j; if(!visit[i]) { visit[i]=1; //代表該頂點已被遍歷 printf("%c ",G->vexs[i]); for(int j=0;j<G->vexNum;j++) { if(!visit[j]&&G->arcs[i][j]==1) //訪問沒有被訪問過得鄰接點 { DFS(G,j,visit); } } } }
5.圖的廣度優先遍歷:從圖中某一個頂點出發,再依次訪問所有的鄰接點,直至所有的頂點均被訪問為止
void BFS(myGraph G,int *visit) //滿足隊列先進先出的特性 { int front=0; int rear=0; int Queue[MAX]; //儲存每個數據的下標 int i,j,k; for(i=0;i<G->vexNum;i++) { visit[i]=0; //先經過了深度優先遍歷,先全部變成未訪問 } for(i=0;i<G->vexNum;i++) //避免出現個人沒有邊的頂點 { if(!visit[i]) { visit[i]=1; //該頂點已被訪問 printf("%c ",G->vexs[i]); Queue[rear++]=i; //第一元素的下標 } while(front!=rear) { j=Queue[front++]; for(k=firstVertex(G,j);k>=0;k=nextVertex(G,j,k)) //將出隊列的所有節點的鄰接點都入隊 { if(!visit[k])//如果沒有被訪問過 { visit[k]=1; Queue[rear++]=k; printf("%c ",G->vexs[k]); } } } } }
所有的代碼如下:
#include<stdio.h> #include<stdlib.h> #define MAX 20 //邊和頂點的最大數量 typedef char ElemType; typedef struct Graph{ int vexNum; //頂點數 int arcNum; //邊的數量 ElemType vexs[MAX]; //頂點信息 int arcs[MAX][MAX]; //邊的信息 }Graph,*myGraph; //獲取頂點的下標 int getLocate(myGraph G,char v) { int i; for(i=0;i<G->vexNum;i++) { if(v==G->vexs[i]) { return i; } } return -1; } //圖的創建 void createGraph(myGraph &G) { G=(Graph*)malloc(sizeof(Graph)); //結構體的指針要初始化 int i,j,k; int vexNum,arcNum; char v1,v2; //邊的兩個頂點 printf("請輸入頂點的數量:"); scanf("%d",&G->vexNum); printf("請輸入邊的數量:"); scanf("%d",&G->arcNum); printf("請依次將頂點數據輸入進來\n"); for(i=0;i<G->vexNum;i++) { getchar(); scanf("%c",&G->vexs[i]); } for(i=0;i<G->vexNum;i++) { for(j=0;j<G->vexNum;j++) { G->arcs[i][j]=0;//初始化矩陣 } } printf("請依次將邊輸入進來\n"); for(i=0;i<G->arcNum;i++) { getchar(); scanf("%c%c",&v1,&v2); j=getLocate(G,v1); k=getLocate(G,v2); G->arcs[j][k]=1; G->arcs[k][j]=1; } } //返回第一個鄰接點坐標 int firstVertex(myGraph G,int i) { if(i<0||i>(G->vexNum-1)) { printf("輸入的下標不正確\n"); return -1; } else { int j; for(int j=0;i<G->vexNum;j++) { if(G->arcs[i][j]==1) { return j; } } return -1; } } //返回下一個鄰接點坐標 int nextVertex(myGraph G,int i,int j) { if(i<0||i>(G->vexNum-1)||j<0||j>(G->vexNum-1)) { printf("輸入的下標不正確\n"); return -1; } else { int k; for(k=j+1;k<G->vexNum;k++) { if(G->arcs[i][k]==1) { return k; } } return -1; } } //圖的深度優先遍歷 void DFS(myGraph G,int i,int *visit) { int j; if(!visit[i]) { visit[i]=1; //代表該頂點已被遍歷 printf("%c ",G->vexs[i]); for(int j=0;j<G->vexNum;j++) { if(!visit[j]&&G->arcs[i][j]==1) //訪問沒有被訪問過得鄰接點 { DFS(G,j,visit); } } } } //圖的廣度優先遍歷 void BFS(myGraph G,int *visit) //滿足隊列先進先出的特性 { int front=0; int rear=0; int Queue[MAX]; //儲存每個數據的下標 int i,j,k; for(i=0;i<G->vexNum;i++) { visit[i]=0; //先經過了深度優先遍歷,先全部變成未訪問 } for(i=0;i<G->vexNum;i++) //避免出現個人沒有邊的頂點 { if(!visit[i]) { visit[i]=1; //該頂點已被訪問 printf("%c ",G->vexs[i]); Queue[rear++]=i; //第一元素的下標 } while(front!=rear) { j=Queue[front++]; for(k=firstVertex(G,j);k>=0;k=nextVertex(G,j,k)) //將出隊列的所有節點的鄰接點都入隊 { if(!visit[k])//如果沒有被訪問過 { visit[k]=1; Queue[rear++]=k; printf("%c ",G->vexs[k]); } } } } } //鄰接矩陣的打印 void printfGraph(myGraph G) { int i,j; printf(" "); for(i=0;i<G->vexNum;i++) { printf("%c ",G->vexs[i]); } printf("\n"); for(i=0;i<G->vexNum;i++) { printf("%c ",G->vexs[i]); for(int j=0;j<G->vexNum;j++) { printf("%d ",G->arcs[i][j]); } printf("\n"); } } int main() { myGraph G; createGraph(G); //圖的鄰接矩陣的建立 printfGraph(G); //圖的輸出 printf("深度優先搜索如下:\n"); int visit[G->vexNum]={0}; for(int i=0;i<G->vexNum;i++) //這里for循環是為了出現沒有被連接邊的頂點 { DFS(G,i,visit); //深度優先搜索 } printf("\n"); printf("廣度優先搜索如下:\n"); BFS(G,visit); free(G); }
該程序的圖的功能可以正常實現,但是圖的廣度優先遍歷會使程序崩潰,但是排序沒有問題,還沒有找到是什么原因導致的