利用一个类构造图的邻接矩阵、邻接表、十字链表、邻接多重表(c++含注释)

前言

新人菜鸟的第一篇博客,有问题欢迎大家交流指正

一、各部分代码展示

1.邻接矩阵的构造

Graph::Graph(int *vertexarray, int *nameofvertex, int numberofvertex)//邻接矩阵的构造函数
{
	vertexnum2 = numberofvertex;
	for (int i = 0; i < vertexnum2; i++)
	{
		vertexname.push_back(nameofvertex[i]);
	}
	adjacencyMatrix.resize(vertexnum2, vector<int>(vertexnum2));
	for (int i = 0; i < vertexnum2; i++)
		for (int j = 0; j < vertexnum2; j++)
			adjacencyMatrix[i][j] = *(vertexarray + i * vertexnum2 + j);
}

2.邻接表的构造

Graph::Graph(int *arcarray, char *arcofname, int numofvertex, int numberofarc)//邻接表的构造函数
{
	this->arcnum1 = numberofarc;
	this->vertexnum1 = numofvertex;
	vertexNode tempvernode; 
	for (int i = 0; i < vertexnum1; i++)
	{
		tempvernode.vertexname = arcofname[i];
		tempvernode.firstedge = NULL;
		tempvernode.visited = false;
		adjacencylist.push_back(tempvernode);
	}
	for (int i = 0; i < arcnum1*3; i+=3)
	{
		ArcNode *parcnode = new ArcNode;
		int arctailindex;
		arctailindex = *(arcarray + i+0);
		parcnode->adjvex = *(arcarray +i+1);
		parcnode->weight = *(arcarray + i+2);
		parcnode->next = adjacencylist[arctailindex].firstedge;
		adjacencylist[arctailindex].firstedge = parcnode;
	}
}

3.十字链表的构造

Graph::Graph(int *matrix, char *nameofvertex, int numberofvertex, int numberofarc,int sigh)//十字链表的构造
{
	ortharcnode* ptemp;
	orthvertexnode tempvexnode;
	if (!orthgrapharray.empty())
		vector<orthvertexnode>().swap(orthgrapharray);//建立并初始化表头向量
	for (int i = 0; i < numberofvertex; i++)
	{
		tempvexnode.data = nameofvertex[i];
		tempvexnode.firstin = NULL;
		tempvexnode.firstout = NULL;
		orthgrapharray.push_back(tempvexnode);
	}
	for(int i = 0 ; i < numberofvertex ; i++)
		for(int j = 0 ; j < numberofvertex ; j++)
			if (matrix[i*numberofvertex + j] != 0)//如果i行j列非零
			{
				ortharcnode* portharcnode = new ortharcnode;//生成十字链表弧结点
				portharcnode->tailvex = i;
				portharcnode->headvex = j;
				portharcnode->headlink = NULL;
				portharcnode->taillink = NULL;
				//插入行链表
				if (orthgrapharray[i].firstout == NULL || orthgrapharray[i].firstout->headvex > j)
				{
					portharcnode->taillink = orthgrapharray[i].firstout;
					orthgrapharray[i].firstout = portharcnode;
				}
				else
				{
					//寻找行插入的位置
					for (ptemp = orthgrapharray[i].firstout; (ptemp->taillink != NULL) && ptemp->taillink->headvex < j; ptemp = ptemp->taillink);
					portharcnode->taillink = ptemp->taillink;
					ptemp->taillink = portharcnode;
				}
				//插入列向量
				if (orthgrapharray[j].firstin == NULL || orthgrapharray[j].firstin->tailvex > i)
				{
					portharcnode->headlink = orthgrapharray[j].firstin;
					orthgrapharray[j].firstin = portharcnode;
				}
				else
				{
					//寻找列插入的位置
					for (ptemp = orthgrapharray[j].firstin; (ptemp->headlink != NULL) && ptemp->headlink->tailvex < i; ptemp = ptemp->headlink);
					portharcnode->headlink = ptemp->headlink;
					ptemp->headlink - portharcnode;
				}
			}
}

4.邻接多重表的构造

Graph::Graph(int *matrix, char *nameofvertex, int numberofvertex)//邻接多重表的构造
{
	multilistedgenode* ptemp;
	multilistvexnode tempvexnode;
	if (!multilistgrapharray.empty())
		vector<multilistvexnode>().swap(multilistgrapharray);//建立并初始化表头向量
	for (int i = 0; i < numberofvertex; i++)
	{
		tempvexnode.data = nameofvertex[i];
		tempvexnode.firstedge = NULL;
		multilistgrapharray.push_back(tempvexnode);
	}
	for (int i = 0; i < numberofvertex; i++)
	{
		for (int j = i + 1; j < numberofvertex; j++)
		{
			if (matrix[i*numberofvertex + j] != 0)
			{
				//生成邻接多重表节点
				multilistedgenode* pmultilistedgenode = new multilistedgenode;
				pmultilistedgenode->ivex = i;
				pmultilistedgenode->jvex = j;
				pmultilistedgenode->ilink = NULL;
				pmultilistedgenode->jlink = NULL;
				//插入行链表
				pmultilistedgenode->ilink = multilistgrapharray[i].firstedge;
				multilistgrapharray[i].firstedge = pmultilistedgenode;
				//插入列链表
				pmultilistedgenode->jlink = multilistgrapharray[j].firstedge;
				multilistgrapharray[j].firstedge = pmultilistedgenode;
			}
		}
	}
}

二、 完整代码

#include<iostream>
#include<queue>
#include<stack>
#include<vector>
#include<string>
#include<stdio.h>

using namespace std;

struct ArcNode//定义弧标节点
{
	int adjvex;
	int weight;
	ArcNode *next;
};

struct vertexNode//定义顶点表节点
{
	char vertexname;
	bool visited;
	int inDegree;
	ArcNode *firstedge;
};

struct ortharcnode//十字链表弧节点结构体定义
{
	int tailvex, headvex;//弧尾和弧头的编号
	ortharcnode *headlink;//弧头相同的下一条弧
	ortharcnode *taillink;//弧尾相同的下一条弧
};

struct orthvertexnode//十字链表头节点结构体定义
{
	char data;//顶点信息
	ortharcnode *firstin;//顶点的第一条入边
	ortharcnode *firstout;//弧尾相同的下一条弧
};

struct multilistedgenode//邻接多重表边结构体定义
{
	int ivex, jvex;//弧尾和弧头的编号
	multilistedgenode *ilink;//弧头相同的下一条弧
	multilistedgenode *jlink;//弧尾相同的下一条弧
};

struct multilistvexnode//邻接多重表顶点结构体定义
{
	char data;//顶点信息
	multilistedgenode *firstedge;//第一条依附顶点的边
};
class Graph
{
public:
	Graph(int *arcarray, char *arcofname, int numofvertex, int numberofarc);//构造邻接表
	Graph(int *vertexarray, int *nameofvertex, int numberofvertex);//构造邻接矩阵
	Graph(int *matrix, char *nameofvertex, int numberofvertex, int numberofarc,int sign);//构造十字链表(sigh的作用是与邻接表的构造区分开)
	Graph(int *matrix, char *nameofvertex, int numberofvertex);//构造邻接多重表
	void printadjacencylist();//邻接表的输出
	void printmatrix();//邻接矩阵的输出
	void printorthlistgraph();//十字链表的输出
	void printmultilistgraph();//邻接多重表的输出
private:
	vector<char> vertexname;//邻接矩阵顶点表
	vector<vector<int>> adjacencyMatrix;//邻接矩阵
	vector <vertexNode> adjacencylist;//存放图中的顶点和数组
	vector<orthvertexnode> orthgrapharray;//十字链表表头向量
	vector<multilistvexnode> multilistgrapharray;//邻接多重表表头向量
	int vertexnum1, arcnum1;//图的顶点数和弧度
	int vertexnum2, arcnum2;//图的顶点数和边数
	int rows, cols, numbers;//稀疏矩阵行数,列数,非零元素个数
};

Graph::Graph(int *arcarray, char *arcofname, int numofvertex, int numberofarc)//邻接表的构造函数
{
	this->arcnum1 = numberofarc;
	this->vertexnum1 = numofvertex;
	vertexNode tempvernode; 
	for (int i = 0; i < vertexnum1; i++)
	{
		tempvernode.vertexname = arcofname[i];
		tempvernode.firstedge = NULL;
		tempvernode.visited = false;
		adjacencylist.push_back(tempvernode);
	}
	for (int i = 0; i < arcnum1*3; i+=3)
	{
		ArcNode *parcnode = new ArcNode;
		int arctailindex;
		arctailindex = *(arcarray + i+0);
		parcnode->adjvex = *(arcarray +i+1);
		parcnode->weight = *(arcarray + i+2);
		parcnode->next = adjacencylist[arctailindex].firstedge;
		adjacencylist[arctailindex].firstedge = parcnode;
	}
}

Graph::Graph(int *vertexarray, int *nameofvertex, int numberofvertex)//邻接矩阵的构造函数
{
	vertexnum2 = numberofvertex;
	for (int i = 0; i < vertexnum2; i++)
	{
		vertexname.push_back(nameofvertex[i]);
	}
	adjacencyMatrix.resize(vertexnum2, vector<int>(vertexnum2));
	for (int i = 0; i < vertexnum2; i++)
		for (int j = 0; j < vertexnum2; j++)
			adjacencyMatrix[i][j] = *(vertexarray + i * vertexnum2 + j);
}

Graph::Graph(int *matrix, char *nameofvertex, int numberofvertex, int numberofarc,int sigh)//十字链表的构造
{
	ortharcnode* ptemp;
	orthvertexnode tempvexnode;
	if (!orthgrapharray.empty())
		vector<orthvertexnode>().swap(orthgrapharray);//建立并初始化表头向量
	for (int i = 0; i < numberofvertex; i++)
	{
		tempvexnode.data = nameofvertex[i];
		tempvexnode.firstin = NULL;
		tempvexnode.firstout = NULL;
		orthgrapharray.push_back(tempvexnode);
	}
	for(int i = 0 ; i < numberofvertex ; i++)
		for(int j = 0 ; j < numberofvertex ; j++)
			if (matrix[i*numberofvertex + j] != 0)//如果i行j列非零
			{
				ortharcnode* portharcnode = new ortharcnode;//生成十字链表弧结点
				portharcnode->tailvex = i;
				portharcnode->headvex = j;
				portharcnode->headlink = NULL;
				portharcnode->taillink = NULL;
				//插入行链表
				if (orthgrapharray[i].firstout == NULL || orthgrapharray[i].firstout->headvex > j)
				{
					portharcnode->taillink = orthgrapharray[i].firstout;
					orthgrapharray[i].firstout = portharcnode;
				}
				else
				{
					//寻找行插入的位置
					for (ptemp = orthgrapharray[i].firstout; (ptemp->taillink != NULL) && ptemp->taillink->headvex < j; ptemp = ptemp->taillink);
					portharcnode->taillink = ptemp->taillink;
					ptemp->taillink = portharcnode;
				}
				//插入列向量
				if (orthgrapharray[j].firstin == NULL || orthgrapharray[j].firstin->tailvex > i)
				{
					portharcnode->headlink = orthgrapharray[j].firstin;
					orthgrapharray[j].firstin = portharcnode;
				}
				else
				{
					//寻找列插入的位置
					for (ptemp = orthgrapharray[j].firstin; (ptemp->headlink != NULL) && ptemp->headlink->tailvex < i; ptemp = ptemp->headlink);
					portharcnode->headlink = ptemp->headlink;
					ptemp->headlink - portharcnode;
				}
			}
}

Graph::Graph(int *matrix, char *nameofvertex, int numberofvertex)//邻接多重表的构造
{
	multilistedgenode* ptemp;
	multilistvexnode tempvexnode;
	if (!multilistgrapharray.empty())
		vector<multilistvexnode>().swap(multilistgrapharray);//建立并初始化表头向量
	for (int i = 0; i < numberofvertex; i++)
	{
		tempvexnode.data = nameofvertex[i];
		tempvexnode.firstedge = NULL;
		multilistgrapharray.push_back(tempvexnode);
	}
	for (int i = 0; i < numberofvertex; i++)
	{
		for (int j = i + 1; j < numberofvertex; j++)
		{
			if (matrix[i*numberofvertex + j] != 0)
			{
				//生成邻接多重表节点
				multilistedgenode* pmultilistedgenode = new multilistedgenode;
				pmultilistedgenode->ivex = i;
				pmultilistedgenode->jvex = j;
				pmultilistedgenode->ilink = NULL;
				pmultilistedgenode->jlink = NULL;
				//插入行链表
				pmultilistedgenode->ilink = multilistgrapharray[i].firstedge;
				multilistgrapharray[i].firstedge = pmultilistedgenode;
				//插入列链表
				pmultilistedgenode->jlink = multilistgrapharray[j].firstedge;
				multilistgrapharray[j].firstedge = pmultilistedgenode;
			}
		}
	}
}

void Graph::printadjacencylist()//邻接表的输出
{
	cout << "图的邻接表表示为:" << endl;
	int index;
	ArcNode *curarcnode;
	for (int i = 0; i < adjacencylist.size(); i++)
	{
		cout << adjacencylist[i].vertexname;
		curarcnode = adjacencylist[i].firstedge;
		if (curarcnode != NULL)
		{
			while (curarcnode != NULL)
			{
				cout << "--->" << "(" << adjacencylist[curarcnode->adjvex].vertexname << "权值为:" << curarcnode->weight << ")";
				curarcnode = curarcnode->next;
			}
		}
		else
			cout << "--->" << "空";
		cout << endl;
	}
}

void Graph::printmatrix()//邻接矩阵的输出
{
	cout << "图的邻接矩阵表示为:" << endl;
	for (int i = 0; i < vertexnum2; i++)//遍历输出所有数值
	{
		for (int j = 0; j < vertexnum2; j++)
		{
			if (adjacencyMatrix[i][j] != 1001)
				cout << adjacencyMatrix[i][j] << "   ";
			else
				cout << "oo" << "  ";
		}
		cout << endl;
	}
}

void Graph::printorthlistgraph()//十字链表的输出
{
	cout << "图十字链表的为:" << endl;
	cout << "按行输出为:" << endl;
	for (int i = 0; i < orthgrapharray.size(); i++)
	{
		for (ortharcnode* ptemp = orthgrapharray[i].firstout; ptemp != NULL; ptemp = ptemp->taillink)
			cout << orthgrapharray[ptemp->tailvex].data << "--->" << orthgrapharray[ptemp->headvex].data << "  ";
		cout << endl;
	}
	cout << "按列输出为:" << endl;
	for (int i = 0; i < orthgrapharray.size(); i++)
	{
		for (ortharcnode* ptemp = orthgrapharray[i].firstin; ptemp != NULL; ptemp = ptemp->headlink)
			cout << orthgrapharray[ptemp->tailvex].data << "--->" << orthgrapharray[ptemp->headvex].data << "  ";
		cout << endl;
	}
	cout << endl;
}

void Graph::printmultilistgraph()//邻接多重表的输出
{
	cout << "图的邻接多重表输出为:" << endl;
	for (int i = 0; i < multilistgrapharray.size(); i++)
	{
		cout << multilistgrapharray[i].data << "的邻接点有:";
		multilistedgenode* pmultilistedgenode = multilistgrapharray[i].firstedge;
		while (pmultilistedgenode != NULL)
		{
			int index = pmultilistedgenode->ivex == i ? pmultilistedgenode->jvex : pmultilistedgenode->ivex;
			cout << multilistgrapharray[index].data << " ";
			pmultilistedgenode = pmultilistedgenode->ivex == i ? pmultilistedgenode->ilink : pmultilistedgenode->jlink;
		}
		cout << endl;
	}
}

int main()
{
	int G[1000], name1[10], m, n,i;
	char name2[10];
	cout << "请输入指令:" << endl;
	cout << "1:构造邻接矩阵" << endl << "2:构造邻接表" << endl << "3:构造十字链表" << endl << "4:构造邻接重表" << endl<<"5:结束构造"<<endl;
	while (scanf_s("%d", &i) != EOF)
	{
		if (i == 1)
		{
			cout << "请输入节点个数" << endl;
			cin >> m;
			cout << "请输入节点的名字(int型)" << endl;
			for (int i = 0; i < m; i++)
				cin >> name1[i];
			cout << "请以"<<m<<"维矩阵的形式输入" << endl;
			for (int x = 0; x < m; x++)
				for (int y = 0; y < m; y++)
					cin >> G[x*m + y];
			Graph A(G, name1, m);
			A.printmatrix();
			cout << endl;
		}
		else if (i == 2)
		{
			cout << "请输入节点个数" << endl;
			cin >> m;
			cout << "请输入弧的个数" << endl;
			cin >> n;
			cout << "请输入节点的名字(char型)" << endl;
			for (int j = 0; j < m; j++)
				cin >> name2[j];
			getchar();
			cout << "请依次输入弧的信息(弧头,弧尾,权重:弧头弧尾要以int型输入表示第几个点)" << endl;
			for (int j = 0; j < n*3; j += 3)
				cin >> G[j] >> G[j + 1] >> G[j + 2];
			Graph A(G, name2, m, n);
			A.printadjacencylist();
			cout << endl;
		}
		else if (i == 3)
		{
			cout << "请输入节点个数" << endl;
			cin >> m;
			cout << "请输入节点的名字(char型)" << endl;
			for (int j = 0; j < m; j++)
				cin >> name2[j];
			getchar();
			cout << "请以" << m << "维矩阵的形式输入" << endl;
			for (int x = 0; x < m; x++)
				for (int y = 0; y < m; y++)
					cin >> G[x*m + y];
			Graph A(G, name2, m, m, 0);
			A.printorthlistgraph();
		}
		else if (i == 4)
		{
			cout << "请输入节点个数" << endl;
			cin >> m;
			cout << "请输入节点的名字(char型)" << endl;
			for (int j = 0; j < m; j++)
				cin >> name2[j];
			getchar();
			cout << "请以" << m << "维矩阵的形式输入" << endl;
			for (int x = 0; x < m; x++)
				for (int y = 0; y < m; y++)
					cin >> G[x*m + y];
			Graph A(G, name2, m);
			A.printmultilistgraph();
		}
		else
			return 0;
		cout << "请输入指令:" << endl;
		cout << "1:构造邻接矩阵" << endl << "2:构造邻接表" << endl << "3:构造十字链表" << endl << "4:构造邻接重表" << endl << "5:结束构造" << endl;
	}
}
对任意给定的(顶点数不小于20,边数不少于30,型可以是有向、无向、有向网、无向网),能够输入的顶点和边(或弧)的信息,并存储到相应存储结构(邻接矩阵邻接表十字链表邻接多重表,任选其中两种型),对自己所创建的完成以下操作: 对无向求每个顶点的度,或对有向求每个顶点的入度和出度(5分) 完成插入顶点和边(或弧)的功能(5分) 完成删除顶点和边(或弧)的功能(5分) 两种存储结构的转换(5分),如果其中一种存储结构为十字链表邻接多重表则增加5分。 输出的深度优先遍历序列或广度优先遍历序列(5分) 求的深度优先或广度优先的生成树(或生成森林)(存储结构为孩子-兄弟链表),并对生成树进行遍历(15分) 判断的连通性,输出连通分量的个数(5分) 判断中是否存在环,无向5分,有向10分 给出顶点u和v,判断u到v是否存在路径(5分) 10、求顶点u到v的一条简单路径(10分) 11、求顶点u到v的所有简单路径(15分) 12、求顶点u到v的最短路径(10分) 13、求顶点u到其余各顶点的最短路径(15分) 14、求任两个顶点之间的最短路径(15分) 15、求最小生成树(15分) 16、对于有一个源点和一个汇点的有向网,求关键路径(20分) 编程环境可以是C、VC++、JAVA,每位同学从上述题目中选择100分的题目,注意,必须选择第1-6题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值