图(邻接矩阵->邻接表:邻接表->邻接矩阵)

本文探讨了如何在具有n个节点的无全图中进行图的存储结构转换,包括从邻接矩阵到邻接表以及从邻接表回转到邻接矩阵的过程,并详细分析了这两个算法的时间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题:对于具有n个结点的不带全图G

1.)设计一个将邻接矩阵转换为邻接表的算法;

(2.)设计一个将邻接表转换为邻接矩阵的算法;

(3.)分析算法的时间复杂度。

/*
图的存储形式转换

	1.通过矩阵存储形式创建图
	2.输出矩阵存储形式结果
	3.邻接表存储->邻接矩阵存储
	4.输出邻接表形式存储结果
	5.邻接矩阵存储->邻接表存储
	6.输出矩阵存储形式结果->判断是否有错
*/

#include<iostream>
#include<string>
#include<fstream>
using namespace std;

//定义矩阵空间
const int MAX_N = 100;

//邻接矩阵存储
class Vertex
{
public:
	int number;//给顶点定义顶点下标
	char info;//顶点信息
};

//图->邻接矩阵存储
class MGraph
{
public:
	int edges[MAX_N][MAX_N];//边数组
	int Tpoints, Tedges;//顶点总数;边总数
	Vertex m_vert[MAX_N];//存放顶点信息
};


//邻接表存储
//顶点信息
class Anode;
class Vnode
{
public:
	char adjvex;//顶点信息
	Anode *firstAnode;//下一顶点
};

//边信息
class Anode
{
public:
	int iverx;//next ver
	class Anode *nextAnode;
};

//图->临接表存储
class AGraph
{
public:
	Vnode adjList[MAX_N];
	int Tpoints, Tedges;

};

//图
class Graph
{
public:
	Graph()
	{
		InitMatrix();//邻接矩阵存储初始化
	}
	~Graph(){}

	/*
	*	临接矩阵存储->创建图
	*/

	//邻接矩阵存储初始化
	void InitMatrix()
	{
		for (int i = 0; i < MAX_N; i++)
		{
			for (int j = 0; j < MAX_N; j++)
			{
				graph.edges[i][j] = 0;//所有点初始化为0
			}
		}
	}

	//读取文件数据
	void readFileInfo(char* filename)
	{
		int i = 0;
		string str;
		ifstream readfile;
		readfile.open(filename);
		getline(readfile, vers);//读取顶点
		while (!readfile.eof())
		{
			if (getline(readfile, str).good())
			{
				edges[i].assign(str);//读取边
				i++;
			}
		}
		readfile.close();
		count_edges = i;//边数
	}

	//创建图
	void CreateGraphMat()
	{
		graph.Tpoints = vers.length();//顶点数
		graph.Tedges = count_edges;//边数
		//存放顶点
		for (int i = 0; i < graph.Tpoints; i++)
		{
			graph.m_vert[i].info = vers[i];
			graph.m_vert[i].number = i;
		}
		//存放边
		for (int i = 0; i < graph.Tedges; i++)
		{
			int p1 = location(graph, edges[i][0]);//获取对应边前一顶点的下标
			int p2 = location(graph, edges[i][1]);//获取同一条边后一点的下标
			graph.edges[p1][p2] = graph.edges[p2][p1] = 1;//在对应矩阵中存储为1,为修改的值为0->不存在边
		}
	}

	//搜索下标
	int location(MGraph g, char ch)
	{
		for (int i = 0; i < g.Tpoints; i++)
		{
			if (g.m_vert[i].info == ch)
			{
				return i;
			}
		}
		return -1;
	}

	//输出
	void display()
	{
		cout << "Matrix Way" << endl;
		//输出顶点以及对应下标
		cout << "point" << endl;
		for (int i = 0; i < graph.Tpoints; i++)
		{
			cout << graph.m_vert[i].info << "->";//顶点
			cout << graph.m_vert[i].number << endl;//顶点下标
		}
		//输出邻接矩阵
		cout << endl << "Matrix" << endl;
		for (int i = 0; i < graph.Tpoints; i++)
		{
			for (int j = 0; j < graph.Tpoints; j++)
			{
				cout << graph.edges[i][j] << ends;
			}
			cout << endl;
		}
		cout << endl;
	}

	/*
	*	邻接表形式存储与邻接矩阵存储相互转换
	*/

	//输出
	void fdisplay()
	{
		//对用值为边的下标
		//对照邻接矩阵输出结果的相应位置
		cout << "Form Way" << endl;
		cout << "output the index of the vertex" << endl;
		Anode *p;
		for (int i = 0; i < graph.Tpoints; i++)
		{
			p = fgraph->adjList[i].firstAnode;//头结点赋值
			while (p != NULL)//遍历当前头结点的后序节点
			{
				cout << p->iverx << ends;//输出对应下标
				p = p->nextAnode;
			}
			cout << endl;
		}
		cout << endl;
	}
	
	//临接矩阵转换成邻接表存储
	void MatToList()
	{
		int i, j;
		Anode *p;
		fgraph = (AGraph *)malloc(sizeof(AGraph));
		for (i = 0; i < graph.Tpoints; i++)
		{
			fgraph->adjList[i].firstAnode = NULL;//头结点组初始化赋值为空->头插法生成单链表组
		}
		for (i = 0; i < graph.Tpoints; i++)
		{
			for (j = graph.Tpoints - 1; j >= 0; j--)//倒序
			{
				if (graph.edges[i][j] != 0)
				{
					p = (Anode *)malloc(sizeof(Anode));
					//头插法
					p->iverx = j;
					p->nextAnode = fgraph->adjList[i].firstAnode;
					fgraph->adjList[i].firstAnode = p;
				}
			}
		}
		//顶点数和边数赋值
		fgraph->Tpoints = graph.Tpoints;
		fgraph->Tedges = graph.Tedges;
	}

	//邻接表转换成邻接矩阵存储
	void ListToMat()
	{
		int i;
		Anode *p;
		for (i = 0; i < fgraph->Tpoints; i++)
		{
			p = fgraph->adjList[i].firstAnode;//指向头结点组
			while (p != NULL)
			{
				graph.edges[i][p->iverx] = 1;//对应不为空的节点赋值为1,未处理的矩阵空间均为0
				p = p->nextAnode;
			}
		}
		//顶点数和边数
		graph.Tpoints = fgraph->Tpoints;
		graph.Tedges = fgraph->Tedges;
	}
private:
	MGraph graph;//临接矩阵存储图
	AGraph *fgraph;//邻接表存储图
	string vers;//顶点
	string edges[MAX_N];//边
	int count_edges;//边数
};

int main()
{
	Graph g;
	g.readFileInfo("data");//读取文件信息
	g.CreateGraphMat();//矩阵形式构建
	g.display();//输出->矩阵形式
	g.MatToList();//矩阵存储形式转换为表
	g.fdisplay();//输出->表存储形式
	g.ListToMat();//表形式转换为矩阵形式
	g.display();//输出->矩阵形式;观察是否出错
	return 0;
}
测试结果



评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值