图3——把邻接矩阵转换为邻接表

【分析】这是哈工大的考研题。由于有向图和无向图的邻接存储结构不同,并与带权图的存储存在一定差别,这里给出有向图的邻接矩阵到邻接表的转换。

#include 
#include 
#include 
#include 
#include 
#include 

typedef char VertexType[4];
typedef char InfoPtr;
typedef int VRType;

using namespace std;
#define MAXSIZE 50
typedef enum{DG,DN,UG,UN} GraphKind;//有向图,有向网,无向图,无向网
//定义邻接矩阵类型
typedef struct  
{
	VRType adj;
	InfoPtr *info;

}AdjMatrix[MAXSIZE][MAXSIZE];
typedef struct 
{
	VertexType vex[MAXSIZE];
	AdjMatrix arc;
	int vexnum, arcnum;
	GraphKind kind;

}MGraph;
typedef struct ArcNode
{
	int adjvex;
	InfoPtr *info;
	struct ArcNode *nextarc;
}ArcNode;

typedef struct VNode
{
	VertexType data;
	ArcNode *firstarc;

}VNode,AdjList[MAXSIZE];
typedef struct 
{
	AdjList vertex;
	int vexnum, arcnum;
	GraphKind kind;
}AdjGraph;

void CreateGraph(MGraph *G);
int LocateVertex(MGraph G, VertexType v);
void DestroyGraph(MGraph *G);
void DisplayGraph(MGraph G);
void DisplayAdjGraph(AdjGraph G);
void ConvertGraph(AdjGraph *A, MGraph M);
void main()
{
	MGraph M;
	AdjGraph A;
	cout << "创建一个有向图:" << endl;
	CreateGraph(&M);
	cout << "输出顶点和弧:" << endl;
	DisplayGraph(M);
	ConvertGraph(&A, M);
	DisplayAdjGraph(A);
	DestroyGraph(&M);
	system("pause");

}

void CreateGraph(MGraph *G)
{
	int i, j, k;
	VertexType v1, v2;
	cout << "请输入有向图的顶点数和弧数:" << endl;
	cin >> (*G).vexnum >> (*G).arcnum;
	cout << "请输入"<vexnum<<"个顶点的值:" << endl;

	for (i = 0; i < G->vexnum;i++)
	{
		cin >> G->vex[i];
	}
	for (i = 0; i < G->vexnum;i++)
	{
		for (j = 0; j < G->vexnum;j++)
		{
			G->arc[i][j].adj = 0;
			G->arc[i][j].info = NULL;
		}
	}
	cout << "请输入" << G->arcnum << "条弧的弧尾 弧头(以空格分隔)" << endl;
	for (k = 0; k < G->arcnum;k++)
	{
		cin >> v1 >> v2;
		i = LocateVertex(*G, v1);
		j = LocateVertex(*G, v2);
		G->arc[i][j].adj = 1;
	}

	G->kind = DG;

}

int LocateVertex(MGraph G, VertexType v)
{
	int i;
	for (i = 0; i < G.vexnum;++i)
	{
		if (strcmp(G.vex[i],v)==0)
		{
			return i;
		}
		
	}
	return -1;
}

void DestroyGraph(MGraph *G)
{
	int i, j;
	for (i = 0; i < G->vexnum;i++)
	{
		for (j = 0; j < G->vexnum;j++)
		{
			if (G->arc[i][j].adj!=0)
			{
				if (G->arc[i][j].info!=NULL)
				{
					free(G->arc[i][j].info);
					G->arc[i][j].info = NULL;
				}

				G->vexnum = 0;
				G->arcnum = 0;
			}
		}
	}
}

void DisplayGraph(MGraph G)
{
	int i, j;
	cout << "有向图具有" << G.vexnum << "个顶点 " << G.arcnum << "条弧,顶点顶点依次是:" ;
	for (i = 0; i < G.vexnum;++i)
	{
		cout << " " << G.vex[i];

	}
	cout << endl << "有向图G: " << endl;
	cout << "顶点:";
	for (i = 0; i < G.vexnum;i++)
	{
		cout << setw(4) << G.vex[i];
	}
	cout << endl;
	for (i = 0; i < G.vexnum;i++)
	{
		cout << setw(6) << G.vex[i];
		for (j = 0; j < G.vexnum;j++)
		{
			cout << setw(4) << G.arc[i][j].adj;
		}
		cout << endl;
	}

}
void ConvertGraph(AdjGraph *A, MGraph M)
{
	int i, j;
	ArcNode *p;
	A->vexnum = M.vexnum;
	A->arcnum = M.arcnum;
	A->kind = M.kind;
	for (i = 0; i < A->vexnum;i++)
	{
		strcpy(A->vertex[i].data, M.vex[i]);
		A->vertex[i].firstarc = NULL;
	}
	printf("请输入弧尾和弧头(以空格作为间隔):\n");
	for (i = 0; i < M.arcnum;i++)
	{
		for (j = 0; j < M.arcnum;j++)
		{
			if (M.arc[i][j].adj==1)
			{
				p = (ArcNode*)malloc(sizeof(ArcNode));
				p->adjvex = j;
				p->info = NULL;
				p->nextarc = A->vertex[i].firstarc;
				A->vertex[i].firstarc = p;
			}
			(*A).kind = DG;
		}
	}
}

void DisplayAdjGraph(AdjGraph G)
{
	int i;
	ArcNode *p;
	cout << G.vexnum << "个顶点:" << endl;
	for (i = 0; i < G.vexnum;i++)
	{
		cout << G.vertex[i].data << " ";
	}
	cout << endl << G.arcnum << "条边:" << endl;
	for (i = 0; i < G.vexnum;i++)
	{
		p = G.vertex[i].firstarc;
		while (p)
		{
			cout << G.vertex[i].data << "->"<adjvex].data<<" ";
			p = p->nextarc;

		}
		cout << endl;
	}
}

结果:

图3——把邻接矩阵转换为邻接表_第1张图片

 

你可能感兴趣的:(数据结构与算法,图,数据结构与算法)