图的顺序存储(邻接矩阵存储)【摘录自严长生老师的网站】
生活随笔
收集整理的這篇文章主要介紹了
图的顺序存储(邻接矩阵存储)【摘录自严长生老师的网站】
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
圖是表達多對多關系的一種數(shù)據(jù)結構,組成要素為頂點和連接頂點的邊。
根據(jù)邊有無方向可分為有向圖和無向圖
當邊有權重時,升級為有向網(wǎng)和無向網(wǎng)
圖在存儲時,可采用鄰接矩陣,比如下面的無向圖(A)和(B)
用鄰接矩陣可分別表示為下面這樣
每一行代表一個頂點,每一列也對應一個頂點,對于無向圖,邊沒有方向,頂點之間相互連接,則對應位置設為1,否則為0,無向圖的鄰接矩陣是對稱的。
對于有向圖,邊是有方向的,所以有向圖的邊不叫邊,叫有向邊或者弧,個人覺得有向邊更直觀,那么有向圖的行,代表著該頂點到達哪些頂點,可達的記為1,否則為0,有向圖的列,代表著該頂點可由哪些頂點到達,可達的記為1,否則為0。
有了這些基本概念,就可以基于C語言實現(xiàn)其存儲了,注意,這里采用的是鄰接矩陣的存儲方式。
上代碼。
#include <stdio.h> #define MAX_VERtEX_NUM 20 //頂點的最大個數(shù) #define VRType int //表示頂點之間的關系的變量類型 #define InfoType char //存儲弧或者邊額外信息的指針變量類型 #define VertexType int //圖中頂點的數(shù)據(jù)類型 typedef enum{DG,DN,UDG,UDN}GraphKind; //枚舉圖的 4 種類型 typedef struct {VRType adj; //對于無權圖,用 1 或 0 表示是否相鄰;對于帶權圖,直接為權值。InfoType * info; //弧或邊額外含有的信息指針 }ArcCell,AdjMatrix[MAX_VERtEX_NUM][MAX_VERtEX_NUM]; typedef struct {VertexType vexs[MAX_VERtEX_NUM]; //存儲圖中頂點數(shù)據(jù)AdjMatrix arcs; //二維數(shù)組,記錄頂點之間的關系int vexnum,arcnum; //記錄圖的頂點數(shù)和弧(邊)數(shù)GraphKind kind; //記錄圖的種類 }MGraph; //根據(jù)頂點本身數(shù)據(jù),判斷出頂點在二維數(shù)組中的位置 int LocateVex(MGraph * G,VertexType v){int i=0;//遍歷一維數(shù)組,找到變量vfor (; i<G->vexnum; i++) {if (G->vexs[i]==v) {break;}}//如果找不到,輸出提示語句,返回-1if (i>G->vexnum) {printf("no such vertex.\n");return -1;}return i; } //構造有向圖 void CreateDG(MGraph *G){//輸入圖含有的頂點數(shù)和弧的個數(shù)scanf("%d,%d",&(G->vexnum),&(G->arcnum));//依次輸入頂點本身的數(shù)據(jù)for (int i=0; i<G->vexnum; i++) {scanf("%d",&(G->vexs[i]));}//初始化二維矩陣,全部歸0,指針指向NULLfor (int i=0; i<G->vexnum; i++) {for (int j=0; j<G->vexnum; j++) {G->arcs[i][j].adj=0;G->arcs[i][j].info=NULL;}}//在二維數(shù)組中添加弧的數(shù)據(jù)for (int i=0; i<G->arcnum; i++) {int v1,v2;//輸入弧頭和弧尾scanf("%d,%d",&v1,&v2);//確定頂點位置int n=LocateVex(G, v1);int m=LocateVex(G, v2);//排除錯誤數(shù)據(jù)if (m==-1 ||n==-1) {printf("no this vertex\n");return;}//將正確的弧的數(shù)據(jù)加入二維數(shù)組G->arcs[n][m].adj=1;} } //構造無向圖 void CreateDN(MGraph *G){scanf("%d,%d",&(G->vexnum),&(G->arcnum));for (int i=0; i<G->vexnum; i++) {scanf("%d",&(G->vexs[i]));}for (int i=0; i<G->vexnum; i++) {for (int j=0; j<G->vexnum; j++) {G->arcs[i][j].adj=0;G->arcs[i][j].info=NULL;}}for (int i=0; i<G->arcnum; i++) {int v1,v2;scanf("%d,%d",&v1,&v2);int n=LocateVex(G, v1);int m=LocateVex(G, v2);if (m==-1 ||n==-1) {printf("no this vertex\n");return;}G->arcs[n][m].adj=1;G->arcs[m][n].adj=1;//無向圖的二階矩陣沿主對角線對稱} } //構造有向網(wǎng),和有向圖不同的是二階矩陣中存儲的是權值。 void CreateUDG(MGraph *G){scanf("%d,%d",&(G->vexnum),&(G->arcnum));for (int i=0; i<G->vexnum; i++) {scanf("%d",&(G->vexs[i]));}for (int i=0; i<G->vexnum; i++) {for (int j=0; j<G->vexnum; j++) {G->arcs[i][j].adj=0;G->arcs[i][j].info=NULL;}}for (int i=0; i<G->arcnum; i++) {int v1,v2,w;scanf("%d,%d,%d",&v1,&v2,&w);int n=LocateVex(G, v1);int m=LocateVex(G, v2);if (m==-1 ||n==-1) {printf("no this vertex\n");return;}G->arcs[n][m].adj=w;} } //構造無向網(wǎng)。和無向圖唯一的區(qū)別就是二階矩陣中存儲的是權值 void CreateUDN(MGraph* G){scanf("%d,%d",&(G->vexnum),&(G->arcnum));for (int i=0; i<G->vexnum; i++) {scanf("%d",&(G->vexs[i]));}for (int i=0; i<G->vexnum; i++) {for (int j=0; j<G->vexnum; j++) {G->arcs[i][j].adj=0;G->arcs[i][j].info=NULL;}}for (int i=0; i<G->arcnum; i++) {int v1,v2,w;scanf("%d,%d,%d",&v1,&v2,&w);int m=LocateVex(G, v1);int n=LocateVex(G, v2);if (m==-1 ||n==-1) {printf("no this vertex\n");return;}G->arcs[n][m].adj=w;G->arcs[m][n].adj=w;//矩陣對稱} } void CreateGraph(MGraph *G){//選擇圖的類型scanf("%d",&(G->kind));//根據(jù)所選類型,調(diào)用不同的函數(shù)實現(xiàn)構造圖的功能switch (G->kind) {case DG:return CreateDG(G);break;case DN:return CreateDN(G);break;case UDG:return CreateUDG(G);break;case UDN:return CreateUDN(G);break;default:break;} } //輸出函數(shù) void PrintGrapth(MGraph G) {for (int i = 0; i < G.vexnum; i++){for (int j = 0; j < G.vexnum; j++){printf("%d ", G.arcs[i][j].adj);}printf("\n");} } int main() {MGraph G;//建立一個圖的變量CreateGraph(&G);//調(diào)用創(chuàng)建函數(shù),傳入地址參數(shù)PrintGrapth(G);//輸出圖的二階矩陣return 0; }以下面這張圖為例
對應的輸入輸出為
2 6,10 1 2 3 4 5 6 1,2,5 2,3,4 3,1,8 1,4,7 4,3,5 3,6,9 6,1,3 4,6,6 6,5,1 5,4,5 0 5 0 7 0 0 0 0 4 0 0 0 8 0 0 0 0 9 0 0 5 0 0 6 0 0 0 5 0 0 3 0 0 0 1 0這是按照鄰接矩陣來存儲的,鄰接矩陣的空間開銷是固定的,因此當矩陣比較稠密時比較劃算,當頂點之間的連接比較稀疏時,采用鄰接表更合適。
?
轉載于:https://www.cnblogs.com/wzyuan/p/10007789.html
總結
以上是生活随笔為你收集整理的图的顺序存储(邻接矩阵存储)【摘录自严长生老师的网站】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何监视ps/查询的性能和使用
- 下一篇: Oracle GoldenGate OG