圖的儲存結構(鄰接矩陣)
阿新 • • 發佈:2018-12-25
一、鄰接矩陣(無向圖):
1、圖的鄰接矩陣(Adjacency Matrix)儲存方式是用兩個陣列來表示圖。一個一維陣列儲存圖中頂點資訊,一個二維陣列(稱為鄰接矩陣)儲存圖中的邊或弧的資訊。
2、我們可以設定兩個陣列,頂點陣列為vertex[4]={V0,V1,V2,V3},邊陣列arc[4][4]為對稱矩陣(0表示不存在頂點間的邊,1表示頂點間存在邊)。
3、對稱矩陣:所謂對稱矩陣就是n階矩陣的元滿足a[i][j]=a[j][i](0<=i,j<=n)。即從矩陣的左上角到右下角的主對角線為軸,右上角的元與左下角相對應的元全都是相等的。
4、有了這個二維陣列組成的對稱矩陣,我們就可以很容易地知道圖中的資訊:
--要判定任意兩頂點是否有邊無邊就非常容易了;
--要知道某個頂點的度,其實就是這個頂點Vi在鄰接矩陣中第i行(或第i列)的元素之和;
--求頂點Vi的所有鄰接點就是將矩陣中第i行元素掃描一遍,arc[i][j]為1就是鄰接點。
程式碼:
//無向圖鄰接矩陣 #include<iostream> using namespace std; #define VERTEX 4 typedef struct ArrayGraph { char VertexArr[VERTEX];//頂點元素矩陣 int EdgeArr[VERTEX][VERTEX];//邊矩陣二維陣列 }ArrayGraph; void ArrayGraph_init(ArrayGraph *T);//初始化圖 void ArrayGraph_create(ArrayGraph *T);//建立圖 void ArrayGraph_show(ArrayGraph *T); int main() { ArrayGraph T; ArrayGraph_init(&T); ArrayGraph_create(&T); ArrayGraph_show(&T); return 0; } //先對邊矩陣進行初始化,因為在無向圖的邊矩陣中,對角線上都為0 void ArrayGraph_init(ArrayGraph *T) { int i; for(i=0;i<VERTEX;i++) { T->EdgeArr[i][i]=0; } } //建立一個圖 void ArrayGraph_create(ArrayGraph *T) { //輸入頂點元素,對頂點資料進行初始化 for(int i=0;i<VERTEX;i++) { printf("請輸入第%d個頂點值:",i+1); scanf("%c",&(T->VertexArr[i])); getchar(); } //填充邊關係 for (int j = 0; j <VERTEX; ++j) //填充邊關係 { for (int i = j+1; i < VERTEX; ++i) { printf("若元素%c和%c有邊,則輸入1,否則輸入0\t",T->VertexArr[j],T->VertexArr[i]); scanf("%d",&( T->EdgeArr[j][i])); T->EdgeArr[i][j] = T->EdgeArr[j][i]; //對稱 } } } void ArrayGraph_show(ArrayGraph *T)//顯示圖 { printf("頂點元素如下:\n"); for(int i=0;i<VERTEX;i++) { printf("%5c",T->VertexArr[i]); } printf("\n邊矩陣如下:\n "); for(int i=0;i<VERTEX;++i) { printf("%4c",T->VertexArr[i]); } printf("\n"); for(int i=0;i<VERTEX;i++) { printf("%c",T->VertexArr[i]); for(int j=0;j<VERTEX;j++) { printf("%4d",T->EdgeArr[i][j]); } printf("\n"); } printf("\n"); }
二、鄰接矩陣(有向圖):
1、頂點陣列vertex[4]={V0,V1,V2,V3},弧陣列arc[4][4]也是一個矩陣,但因為是有向圖,所以這個矩陣並不對稱,例如由V1到V0有弧,得到arc[1][0]=1,而V0到V1沒有弧,因此arc[0][1]=0。
2、有向圖要考慮入度和出度,頂點V1的入度為1,正好是第V1列的各數之和,頂點V1的出度為2,正好是第V1行的各數之和。
程式碼:
//有向圖鄰接矩陣 #include<iostream> using namespace std; #define VERTEX 4 typedef struct ArrayGraph { char VertexArr[VERTEX]; int EdgeArr[VERTEX][VERTEX]; }ArrayGraph; void ArrayGraph_init(ArrayGraph *T); void ArrayGraph_create(ArrayGraph *T); void ArrayGraph_show(ArrayGraph *T); int main() { ArrayGraph T; ArrayGraph_init(&T); ArrayGraph_create(&T); ArrayGraph_show(&T); return 0; } //對邊矩陣進行初始化 void ArrayGraph_init(ArrayGraph *T) { for(int i=0;i<VERTEX;i++) { T->EdgeArr[i][i]=0; } } //建立圖 void ArrayGraph_create(ArrayGraph *T) { //輸入頂點元素,對頂點元素進行初始化 for(int i=0;i<VERTEX;i++) { printf("請輸入第%d個頂點值:",i+1); scanf("%c",&T->VertexArr[i]); getchar(); } //對邊矩陣進行初始化 for(int i=0;i<VERTEX;i++) { for(int j=i+1;j<VERTEX;j++) { printf("若元素%c指向%c,則輸入1,否則為0。",T->VertexArr[i],T->VertexArr[j]); scanf("%d",&T->EdgeArr[i][j]); printf("若元素%c指向%c,則輸入1,否則為0。",T->VertexArr[j],T->VertexArr[i]); scanf("%d",&T->EdgeArr[j][i]); } } } void ArrayGraph_show(ArrayGraph *T) { printf("頂點元素如下:\n"); for(int i=0;i<VERTEX;i++) { printf("%4c",T->VertexArr[i]); } printf("\n邊矩陣如下:\n "); for(int i=0;i<VERTEX;i++) { printf("%4c",T->VertexArr[i]); } printf("\n"); for(int i=0;i<VERTEX;i++) { printf("%c",T->VertexArr[i]); for(int j=0;j<VERTEX;j++) { printf("%4d",T->EdgeArr[i][j]); } printf("\n"); } }
三、鄰接矩陣(網):
1、每條邊上帶有權的圖就叫網。
這裡“∞”表示一個計算機允許的、大於所有邊上權值的值。
程式碼:
//有權值無向圖鄰接矩陣
#include<iostream>
using namespace std;
#define VERTEX 4
#define INFINITY 65535
typedef struct ArrayNet
{
char VertexArr[VERTEX];
int EdgeArr[VERTEX][VERTEX];
}ArrayNet;
void ArrayNet_init(ArrayNet *T);
void ArrayNet_create(ArrayNet *T);
void ArrayNet_show(ArrayNet *T);
int main()
{
ArrayNet T;
ArrayNet_init(&T);
ArrayNet_create(&T);
ArrayNet_show(&T);
return 0;
}
void ArrayNet_init(ArrayNet *T)
{
for(int i=0;i<VERTEX;i++)
{
T->EdgeArr[i][i]=65535;
}
}
void ArrayNet_create(ArrayNet *T)
{
for(int i=0;i<VERTEX;i++)
{
printf("請輸入第%d個頂點值:",i+1);
scanf("%c",&T->VertexArr[i]);
getchar();
}
for(int i=0;i<VERTEX;i++)
{
for(int j=i+1;j<VERTEX;j++)
{
printf("輸入頂點%c與頂點%c的權值,如果沒有權值則輸入65535。",T->VertexArr[i],
T->VertexArr[j]);
scanf("%d",&T->EdgeArr[i][j]);
T->EdgeArr[j][i]=T->EdgeArr[i][j];
}
}
}
void ArrayNet_show(ArrayNet*T)//顯示圖
{
printf("頂點元素如下:\n");
for(int i=0;i<VERTEX;i++)
{
printf("%8c",T->VertexArr[i]);
}
printf("\n邊矩陣如下:\n ");
for(int i=0;i<VERTEX;++i)
{
printf("%8c",T->VertexArr[i]);
}
printf("\n");
for(int i=0;i<VERTEX;i++)
{
printf("%-8c",T->VertexArr[i]);
for(int j=0;j<VERTEX;j++)
{
if(T->EdgeArr[i][j]==65535)
{
printf("∞ ");
}
else
{
printf("%-8d",T->EdgeArr[i][j]);
}
}
printf("\n");
}
printf("\n");
}
//有權值有向圖鄰接矩陣
#include<iostream>
using namespace std;
#define VERTEX 4
#define INFINITY 65535
typedef struct ArrayNet
{
char VertexArr[VERTEX];
int EdgeArr[VERTEX][VERTEX];
}ArrayNet;
void ArrayNet_init(ArrayNet *T);
void ArrayNet_create(ArrayNet *T);
void ArrayNet_show(ArrayNet *T);
int main()
{
ArrayNet T;
ArrayNet_init(&T);
ArrayNet_create(&T);
ArrayNet_show(&T);
return 0;
}
//對邊矩陣進行初始化
void ArrayNet_init(ArrayNet *T)
{
for(int i=0;i<VERTEX;i++)
{
T->EdgeArr[i][i]=65535;
}
}
//建立圖
void ArrayNet_create(ArrayNet *T)
{
//輸入頂點元素,對頂點元素進行初始化
for(int i=0;i<VERTEX;i++)
{
printf("請輸入第%d個頂點值:",i+1);
scanf("%c",&T->VertexArr[i]);
getchar();
}
//對邊矩陣進行初始化
for(int i=0;i<VERTEX;i++)
{
for(int j=i+1;j<VERTEX;j++)
{
printf("若元素%c指向%c,則輸入權值,否則輸入65535。",T->VertexArr[i],T->VertexArr[j]);
scanf("%d",&T->EdgeArr[i][j]);
printf("若元素%c指向%c,則輸入權值,否則輸入65535。",T->VertexArr[j],T->VertexArr[i]);
scanf("%d",&T->EdgeArr[j][i]);
}
}
}
void ArrayNet_show(ArrayNet*T)//顯示圖
{
printf("頂點元素如下:\n");
for(int i=0;i<VERTEX;i++)
{
printf("%8c",T->VertexArr[i]);
}
printf("\n邊矩陣如下:\n ");
for(int i=0;i<VERTEX;++i)
{
printf("%8c",T->VertexArr[i]);
}
printf("\n");
for(int i=0;i<VERTEX;i++)
{
printf("%-8c",T->VertexArr[i]);
for(int j=0;j<VERTEX;j++)
{
if(T->EdgeArr[i][j]==65535)
{
printf("∞ ");
}
else
{
printf("%-8d",T->EdgeArr[i][j]);
}
}
printf("\n");
}
printf("\n");
}