图的邻接矩阵与邻接表的建立,c/c++描述

  图里数据节点是多对多的关系。一个节点有多个前驱,也有多个后继。甚至还有无向图,不区分前驱和后继,只需要节点之间有邻接关系即可。因此,描述这种数据关系,需要新的数据结构。
  图有顶点集和边集组成。顶点代表一个数据节点,边代表数据顶点间的邻接关系。
  描述图的数据结构是多种多样的,bilibili里小甲鱼老师也说了,程序编程是没有唯一答案的。能解决问题即可。因为编程的自由度,比数学领域大,不像数学题那样只有唯一一个正确答案。和为数不多的几种解法。程序能解决问题,清晰易懂就是好程序。在前人的基础上改动一些,改进一些,也算是更好的程序。
  图可以用邻接矩阵来描述,包含一个存储所有顶点的数组成员,一个存储顶点间邻接关系的二维矩阵,矩阵元素值表示两个下标对应的两个顶点是否有邻接关系,对于带权边,则矩阵元素值表示对应边的权,还有一个表示顶点数的成员,一个表示边数的成员。如此的一个结构体变量就可以表示图的所有数据信息。
  图也可以用邻接表来表示。因为对于稀疏图来说,用邻接矩阵存储边,太浪费内存。邻接表的结构体成员包括,由单链表表头组成的一维数组和总顶点数成员和总边数成员。每一个表头也是结构体变量:一个成员存储顶点,另一个成员存储指向邻接表节点的指针。邻接表节点也是结构体变量,其一个成员存储与表头顶点邻接的另一个顶点在表头数组里的下标,一个成员存储对应边的权值,最后一个成员是指向下一个表节点的指针。如此,这样的一个邻接表结构体变量也存储了图的所有信息。
  本例题是个练习,包含的函数功能如下:
  函数createGraphAdjMatrix,由图的所有零碎已知信息建立邻接矩阵。
  函数createGraphAdjList,由图的所有零碎已知信息建立邻接表。
  函数matrixToList,由邻接矩阵建立邻接表。
  函数listToMatrix,由邻接表建立邻接矩阵;其实就是对结构体的各成员赋值。
  函数dispalyGraphAdjMatrix,由邻接矩阵输出图的所有信息,以矩阵表示。
  函数displayGrapgAdjList,由邻接表输出图的所有信息,以线性表表示。这两个输出的目的也是为了检测图的结构体变量建立是否准确。
  完整代码如下,先是main函数所在文件代码:

#include
#include
using namespace std;
#define MAXVERTEX 15
#define INFINI 65555

struct GraphAdjaMatrix {
	char vertexes[MAXVERTEX];
	int edges[MAXVERTEX][MAXVERTEX];
	int numVertexes;
	int numEdges;
};

struct AdjaListNode {
	int indexOfVertex;
	int weightOfEdge;
	AdjaListNode* pt;
};

struct AdjListHead {
	char vertex;
	AdjaListNode* pt;
};

struct GraphAdjaList {
	AdjListHead vertexes[MAXVERTEX];
	int numVertexes;
	int numEdges;
};

extern void createGraphAdjMatrix(GraphAdjaMatrix &graphAdjMatrix,
			int numVertexes,int numEdges,int edges[][6],char vertexes[]);
extern void createGraphAdjList(GraphAdjaList &graphAdjList,
			int numVertexes, int numEdges, int edges[][6], char vertexes[]);
extern void matrixToList(GraphAdjaMatrix &graphAdjMatrix, 
			GraphAdjaList &graphAdjList);
extern void listToMatrix(GraphAdjaList &graphAdjList,
	GraphAdjaMatrix &graphAdjMatrix);
extern void dispalyGraphAdjMatrix(GraphAdjaMatrix &graphAdjMatrix);
extern void displayGrapgAdjList(GraphAdjaList &graphAdjList);


int main() {
	GraphAdjaMatrix graphAdjMatrix ;
	GraphAdjaList graphAdjList;
	int numVertexes = 6, numEdges = 10;
	int edges[][6] = {	{0,5,INFINI,7,INFINI,INFINI},
						{INFINI,0,4,INFINI,INFINI,INFINI},
						{8,INFINI,0,INFINI,INFINI,9},
						{INFINI,INFINI,5,0,INFINI,6},
						{INFINI,INFINI,INFINI,5,0,INFINI},
						{3,INFINI,INFINI,INFINI,1,0} };
	char vertexes[] = {'a','b','c','d','e','f'};

	createGraphAdjMatrix(graphAdjMatrix,numVertexes,numEdges,edges,vertexes);
	createGraphAdjList(graphAdjList,numVertexes,numEdges,edges,vertexes);

	GraphAdjaMatrix graphAdjMatrixNew;
	GraphAdjaList graphAdjListNew;

	matrixToList(graphAdjMatrix,graphAdjListNew);
	listToMatrix(graphAdjList,graphAdjMatrixNew);

	dispalyGraphAdjMatrix(graphAdjMatrixNew);
	cout << endl;
	displayGrapgAdjList(graphAdjListNew);

	return 0;
}

  接着是各函数所在源文件代码:

#include
#include
using namespace std;
#define MAXVERTEX 15
#define INFINI 65555

struct GraphAdjaMatrix {
	char vertexes[MAXVERTEX];
	int edges[MAXVERTEX][MAXVERTEX];
	int numVertexes;
	int numEdges;
};

struct AdjaListNode {
	int indexOfVertex;
	int weightOfEdge;
	AdjaListNode* pt;
};

struct AdjListHead {
	char vertex;
	AdjaListNode* pt;
};

struct GraphAdjaList {
	AdjListHead vertexes[MAXVERTEX];
	int numVertexes;
	int numEdges;
};

void createGraphAdjMatrix(GraphAdjaMatrix &graphAdjMatrix,
	int numVertexes, int numEdges, int edges[][6], char vertexes[]) {
	graphAdjMatrix.numVertexes = numVertexes;
	graphAdjMatrix.numEdges = numEdges;
	
	for (int i = 0; i < numVertexes; i++)
		graphAdjMatrix.vertexes[i] = vertexes[i];

	for (int row = 0; row < numVertexes; row++)
		for (int column = 0; column < numVertexes; column++)
			graphAdjMatrix.edges[row][column] = edges[row][column];
}

void createGraphAdjList(GraphAdjaList &graphAdjList,
	int numVertexes, int numEdges, int edges[][6], char vertexes[]){
	graphAdjList.numEdges = numEdges;
	graphAdjList.numVertexes = numVertexes;

	for (int i = 0; i < MAXVERTEX; i++)
		graphAdjList.vertexes[i].pt = NULL;

	for (int i = 0; i < numVertexes; i++)
		graphAdjList.vertexes[i].vertex = vertexes[i];

	AdjaListNode* ptTail = NULL,*ptNew;
	int i, j;
	for ( i = 0; i < numVertexes; i++) 
		for (j = 0; j < numVertexes; j++) 
			if (edges[i][j] != 0 && edges[i][j] != INFINI) {
				ptNew = new AdjaListNode;

				ptNew->indexOfVertex = j;
				ptNew->weightOfEdge = edges[i][j];
			
				if (graphAdjList.vertexes[i].pt == NULL) {
					ptNew->pt = NULL;
					graphAdjList.vertexes[i].pt = ptNew;
					ptTail = ptNew;
				}
				else {
					ptNew->pt = ptTail->pt;
					ptTail->pt = ptNew;
					ptTail = ptNew;
				}
			}
}

void matrixToList(GraphAdjaMatrix &graphAdjMatrix,
		GraphAdjaList &graphAdjList) {
	graphAdjList.numEdges = graphAdjMatrix.numEdges;
	graphAdjList.numVertexes = graphAdjMatrix.numVertexes;

	for (int i = 0; i < MAXVERTEX; i++)
		graphAdjList.vertexes[i].pt = NULL;

	for (int i = 0; i < graphAdjList.numVertexes; i++)
		graphAdjList.vertexes[i].vertex = graphAdjMatrix.vertexes[i];

	AdjaListNode* ptTail = NULL, * ptNew;
	int i, j;
	for (i = 0; i < graphAdjList.numVertexes; i++)
		for (j = 0; j < graphAdjList.numVertexes; j++)
			if (graphAdjMatrix.edges[i][j] != 0 && 
				graphAdjMatrix.edges[i][j] != INFINI) {
				ptNew = new AdjaListNode;

				ptNew->indexOfVertex = j;
				ptNew->weightOfEdge = graphAdjMatrix.edges[i][j];

				if (graphAdjList.vertexes[i].pt == NULL) {
					ptNew->pt = NULL;
					graphAdjList.vertexes[i].pt = ptNew;
					ptTail = ptNew;
				}
				else {
					ptNew->pt = ptTail->pt;
					ptTail->pt = ptNew;
					ptTail = ptNew;
				}
			}
}

void listToMatrix(GraphAdjaList &graphAdjList,
	GraphAdjaMatrix &graphAdjMatrix) {
	graphAdjMatrix.numEdges = graphAdjList.numEdges;
	graphAdjMatrix.numVertexes = graphAdjList.numVertexes;

	for (int i = 0; i < graphAdjMatrix.numVertexes; i++)
		graphAdjMatrix.vertexes[i] = graphAdjList.vertexes[i].vertex;

	int row, column;
	//对邻接矩阵的初始化,主对角线为0,其余统统为无穷大
	for(row = 0 ; row < graphAdjMatrix.numVertexes ; row++)
		for(column = 0 ; column < graphAdjMatrix.numVertexes ; column++)
			if (row == column) 
				graphAdjMatrix.edges[row][column] = 0 ;
			else
				graphAdjMatrix.edges[row][column] = INFINI;
	
	AdjaListNode* pt;
	for (row = 0; row < graphAdjMatrix.numVertexes; row++) {
		pt = graphAdjList.vertexes[row].pt;
		while (pt != NULL) {
			column = pt->indexOfVertex;
			graphAdjMatrix.edges[row][column] = pt->weightOfEdge;
			pt = pt->pt;
		}
	}
}

void dispalyGraphAdjMatrix(GraphAdjaMatrix &graphAdjMatrix) {
	cout << "adjacensy matrix :" << endl;
	int row,column;
	printf("%3c",' ');
	for (row = 0; row < graphAdjMatrix.numVertexes; row++)
		printf("%3c",graphAdjMatrix.vertexes[row]);
	printf("\n");
	for (row = 0; row < graphAdjMatrix.numVertexes; row++) {
		printf("%-3c", graphAdjMatrix.vertexes[row]);
		for (column = 0; column < graphAdjMatrix.numVertexes; column++)
			if (graphAdjMatrix.edges[row][column] == INFINI)
				printf("%3s", "∞");
			else
				printf("%3d",graphAdjMatrix.edges[row][column]);
		cout << endl;
	}
}

void displayGrapgAdjList(GraphAdjaList &graphAdjList) {
	cout << "graph adjacency list :" << endl;
	AdjaListNode* pt;
	for (int i = 0; i < graphAdjList.numVertexes; i++) {
		printf("%2c:",graphAdjList.vertexes[i].vertex);
		pt = graphAdjList.vertexes[i].pt;
		while (pt != NULL) {
			printf("%5d(%d)",pt->indexOfVertex,pt->weightOfEdge);
			pt = pt->pt;
		}
		cout << endl;
	}
}

测试结果如下:
图的邻接矩阵与邻接表的建立,c/c++描述_第1张图片
谢谢阅读

你可能感兴趣的:(数据结构c/c++描述,数据结构,算法,c++,c语言,图搜索算法)