1. 程式人生 > >圖的儲存結構(鄰接矩陣)

圖的儲存結構(鄰接矩陣)

一、鄰接矩陣(無向圖):

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");
}