【数据结构】图及其应用

1 篇文章 0 订阅
1 篇文章 0 订阅

定义图结构体

typedef struct {
	VexType vexs[MAXNUM];
	ArcType arcs[MAXNUM][MAXNUM];
	int vexnum, arcnum;
}AMGraph;

typedef struct ArcNode {
	int adjvex;
	struct ArcNode *nextarc;
	/*AdjType weight;
	/*InfoType   *info;
}ArcNode;

typedef struct VNode {
	VexType  data;
	ArcNode  *firstarc;
}VNode, AdjList[MAXNUM];

typedef struct {
	AdjList  vertices;
	int vexnum, arcnum;
}ALGraph;

问题:

1、编写函数,构造以邻接矩阵表示的图;

2、编写函数,构造以邻接表表示的图;

3、编写函数,实现图的深度优先遍历算法(DFS);(图用邻接表表示)

4、编写函数,实现图的广度优先遍历算法(BFS);(图用邻接表表示)(选做)

5、编写函数,实现求最小生成树的Prim算法;(图用邻接矩阵表示)

6、编写函数,实现求最短路径的Dijkstra算法。(图用邻接矩阵表示)(选做)

算法思想阐述:

邻接矩阵创建无向网:

输入总顶点数和总边数后,初始化该矩阵,使其每个权值初始化为极大值,调用LocateALGVex函数,确定两个顶点在图中的位置后,赋予相应边的权值,同时使其对称边赋予相同的权值。

邻接表创建无向图:

输入总顶点数和总边数后,使每个表头结点的指针域初始化为NULL,输入每条边依附的两个顶点后,将此边插入Vi和Vj对应的两个边链表的头部。

Prim算法:

特点:适用于稠密图,归并顶点,与边数无关

1. 从某顶点 u0 出发,选择与它关联的具有最小权值的边(u0, v),将其顶点加入到生成树的顶点集合U中

2. 每一步从一个顶点在U中,而另一个顶点不在U中的各条边中选择权值最小的边(u, v),把它的顶点加入到U中

3. 直到所有顶点都加入到生成树顶点集合U中为止

Kruskal算法:

特点:适用于稀疏图,归并边,

1.先找出从源点v0到各终点vk的直达路径(v0,vk),即通过一条弧到达的路径。

2.从这些路径中找出一条长度最短的路径(v0,u)

3.然后对其余各条路径进行适当调整:

若在图中存在弧(u,vk),且(v0,u)+(u,vk)<(v0,vk),则以路径(v0,u,vk)代替(v0,vk)

在调整后的各条路径中,再找长度最短的路径。

一、各函数代码如下 

解题一 

/*确定两点在邻接矩阵G中的位置,即顶点数组的下标 */
Status LocateAMGVex(AMGraph G,char x){
	for(int i = 0; i < G.vexnum;i++){
		if(x == G.vexs[i]){
			return i;
		}
	}
	return -1;
}
/*确定两点在邻接表G中的位置,即顶点数组的下标 */
Status LocateALGVex(ALGraph G,char x){
	for(int i = 0; i < G.vexnum	;i++){
		if(x == G.vertices[i].data){
			return i;
		}
	}
	return -1;
}
/*邻接矩阵创建无权无向图*/
Status CreateUDNwom(AMGraph &G){
	char v1,v2;/*两顶点*/
	cout<<"请输入总顶点数和总边数:"<<endl;
	cin>>G.vexnum>>G.arcnum;/*输入总顶点数和总边数*/
	for(int i = 0;i < G.vexnum;i++){/*将各点输入顶点表中*/
		printf("请输入第%d个顶点:\n",i+1);	
		cin>>G.vexs[i];
	}
	for(int i = 0;i < G.vexnum;i++){
		for(int j = 0;j < G.vexnum;j++){/*初始化邻接矩阵,使之每个权值初始化为最大值*/
			G.arcs[i][j] = 0;
		}
	}
	for(int k = 0;k < G.arcnum;k++){
		printf("请输入第%d条边依附的顶点:\n",k+1);
		int i,j,w = 1;
		cin>>v1>>v2;/*输入一条边依附的顶点及其权值*/
		i = LocateAMGVex(G,v1);
		j = LocateAMGVex(G,v2);//确定两点在G中的位置,即顶点数组的下标 
		G.arcs[i][j] = w;/*给边赋值*/ 
		G.arcs[j][i] = w;/*置<v1,v2>的对称边<v2,v1>权值为w*/
	}
	return OK;
}
/*邻接矩阵创建有权无向图*/
Status CreateUDNm(AMGraph &G){
	char v1,v2;/*两顶点*/
	cout<<"请输入总顶点数和总边数:"<<endl;
	cin>>G.vexnum>>G.arcnum;/*输入总顶点数和总边数*/
	for(int i = 0;i < G.vexnum;i++){/*将各点输入顶点表中*/
		printf("请输入第%d个顶点:\n",i+1);	
		cin>>G.vexs[i];
	}
	for(int i = 0;i < G.vexnum;i++){
		for(int j = 0;j < G.vexnum;j++){/*初始化邻接矩阵,使之每个权值初始化为最大值*/
			G.arcs[i][j] = MAXInt;
		}
	}
	for(int k = 0;k < G.arcnum;k++){
		printf("请输入第%d条边依附的顶点及其权值:\n",k+1);
		int i,j,w;/*权值*/
		cin>>v1>>v2>>w;/*输入一条边依附的顶点及其权值*/
		i = LocateAMGVex(G,v1);
		j = LocateAMGVex(G,v2);//确定两点在G中的位置,即顶点数组的下标 
		G.arcs[i][j] = w;/*给边赋值*/ 
		G.arcs[j][i] = w;/*置<v1,v2>的对称边<v2,v1>权值为w*/
	}
	return OK;
}
/*邻接矩阵创建无权有向图*/
Status CreateDNwom(AMGraph &G){
	char v1,v2;/*两顶点*/
	cout<<"请输入总顶点数和总边数:"<<endl;
	cin>>G.vexnum>>G.arcnum;/*输入总顶点数和总边数*/
	for(int i = 0;i < G.vexnum;i++){/*将各点输入顶点表中*/
		printf("请输入第%d个顶点:\n",i+1);	
		cin>>G.vexs[i];
	}
	for(int i = 0;i < G.vexnum;i++){
		for(int j = 0;j < G.vexnum;j++){/*初始化邻接矩阵,使之每个权值初始化为最大值*/
			G.arcs[i][j] = 0;
		}
	}
	for(int k = 0;k < G.arcnum;k++){
		printf("请输入第%d条边依附的顶点:\n",k+1);
		int i,j,w = 1;
		cin>>v1>>v2;/*输入一条边依附的顶点及其权值*/
		i = LocateAMGVex(G,v1);
		j = LocateAMGVex(G,v2);//确定两点在G中的位置,即顶点数组的下标 
		G.arcs[i][j] = w;/*给边赋值*/ 
	}
	return OK;
}
/*邻接矩阵创建有权有向图*/
Status CreateDNm(AMGraph &G){
	char v1,v2;/*两顶点*/
	cout<<"请输入总顶点数和总边数:"<<endl;
	cin>>G.vexnum>>G.arcnum;/*输入总顶点数和总边数*/
	for(int i = 0;i < G.vexnum;i++){/*将各点输入顶点表中*/
		printf("请输入第%d个顶点:\n",i+1);	
		cin>>G.vexs[i];
	}
	for(int i = 0;i < G.vexnum;i++){
		for(int j = 0;j < G.vexnum;j++){/*初始化邻接矩阵,使之每个权值初始化为最大值*/
			G.arcs[i][j] = MAXInt;
		}
	}
	for(int k = 0;k < G.arcnum;k++){
		printf("请输入第%d条边依附的顶点及其权值:\n",k+1);
		int i,j,w;/*权值*/
		cin>>v1>>v2>>w;/*输入一条边依附的顶点及其权值*/
		i = LocateAMGVex(G,v1);
		j = LocateAMGVex(G,v2);//确定两点在G中的位置,即顶点数组的下标 
		G.arcs[i][j] = w;/*给边赋值*/ 
	}
	return OK;
}
/*打印邻接矩阵构造的图*/
void PrintN(AMGraph G){
	cout<<endl;
	for(int i = 0;i < G.vexnum;i++){
		for(int j = 0;j < G.vexnum;j++){
			printf("%5d  ",G.arcs[i][j]);
		}
		cout<<endl;
	}
	cout<<endl;
}
void InitQueue(SqQueue *Q)
{
	Q->front = Q->rear = 0;
}

Status IsEmpty(SqQueue *Q)
{
	if (Q->front == Q->rear)
		return 1;
	else
		return 0;
}
 
void EnQueue(SqQueue *Q,int e)
{
	if ((Q->rear + 1) % MAXNUM == Q->front)
		return;
	else
	{
		Q->data[Q->rear] = e;
		Q->rear = (Q->rear + 1) % MAXNUM;
	}
}

void DeQueue(SqQueue *Q,int *e)
{
	if (Q->rear == Q->front)
		return;
	*e = Q->data[Q->front];
	Q->front = (Q->front + 1) % MAXNUM;
}

Status  FirstVertex(ALGraph graph){
	if(graph.vexnum==0)
	   return -1;
	return 0;
}

Status  NextVertex(ALGraph graph,int v){
	if(v==graph.vexnum-1)
	   return -1;
	return v+1;
}
/* 边的插入*/
void insert(ALGraph* p,int a,int b){/*在图中插入边(a,b)*/
	ArcNode* pp;
	ArcNode* temp;
	temp=new ArcNode;
	temp->adjvex=b;
	temp->nextarc=NULL;
	pp=p->vertices[a].firstarc;
	if(pp==NULL)p->vertices[a].firstarc=temp;
	else{
		while(pp->nextarc!=NULL)
			pp=pp->nextarc;
		pp->nextarc=temp;
	}
}
/* 邻接表构造无向图*/
Status CreateUDG(ALGraph &G){
	char v1,v2;/*两顶点*/
	cout<<"请输入总顶点数(不超过100)和总边数:\n";
	cin>>G.vexnum>>G.arcnum;//输入总顶点数和总边数,-> cin可连续输入 
	for(int i=0;i<G.vexnum;i++){
		printf("请输入第%d个顶点:\n",i+1);
		cin>>G.vertices[i].data;		//输入顶点值 
		G.vertices[i].firstarc=NULL;	//初始化表头结点的指针域为NULL 
	}
	for(int k=0;k<G.arcnum;k++){
		int i,j;
		printf("请输入第%d条边依附的顶点:\n",k+1);
		cin>>v1>>v2;
		i = LocateALGVex(G,v1);
		j = LocateALGVex(G,v2);
		ArcNode *p1 = new ArcNode;//生成一个新的边结点*p1 
		p1->adjvex = j;
		p1->nextarc = G.vertices[i].firstarc;
		G.vertices[i].firstarc = p1;	/*将新结点*p1插入至顶点vi的边表头部*/
		
		ArcNode *p2 = new ArcNode;//生成一个新的边结点*p2 
		p2->adjvex = i;
		p2->nextarc = G.vertices[j].firstarc;
		G.vertices[j].firstarc = p2;		/*将新结点*p2插入至顶点vj的边表头部*/
	}
	return OK;
}
/* 邻接表构造有向图*/
Status CreateDG(ALGraph &G){
	char v1,v2;/*两顶点*/
	cout<<"请输入总顶点数(不超过100)和总边数:\n";
	cin>>G.vexnum>>G.arcnum;//输入总顶点数和总边数,-> cin可连续输入 
	for(int i=0;i<G.vexnum;i++){
		printf("请输入第%d个顶点:\n",i+1);
		cin>>G.vertices[i].data;		//输入顶点值 
		G.vertices[i].firstarc=NULL;	//初始化表头结点的指针域为NULL 
	}
	for(int k=0;k<G.arcnum;k++){
		int i,j;
		printf("请输入第%d条边依附的顶点:\n",k+1);
		cin>>v1>>v2;
		i = LocateALGVex(G,v1);
		j = LocateALGVex(G,v2);
		ArcNode *p1 = new ArcNode;//生成一个新的边结点*p1 
		p1->adjvex = j;
		p1->nextarc = G.vertices[i].firstarc;
		G.vertices[i].firstarc = p1;	/*将新结点*p1插入至顶点vi的边表头部*/
	}
	return OK;
}
/*打印邻接表构造的图*/
void PrintDN(ALGraph G){
	for (int i=0;i<G.vexnum;i++) {
		VNode temp = G.vertices[i];									//将G的顶点信息付给temp
		ArcNode *p = temp.firstarc;							  //将顶点信息temp中的边信息给p
		if (p ==  NULL){
			cout<<G.vertices[i].data;
			cout<<endl;
		}
		else {
			cout<<temp.data;
			while (p)
			{
				cout<<"->";
				cout<<p->adjvex;
				p = p->nextarc;
			}
		}
		cout<<endl;
	}
}
void DFS(ALGraph G, int i){
	visited[i] = 1;
	for(int j=0;j<G.vexnum;j++)
	{
		if(G.vertices[j].firstarc == NULL && !visited[j])
			DFS(G,j);
	}
}
void DFSTraverse(ALGraph G){ /*G可能为非连通图*/
	for(int i=0;i<G.vexnum;i++)
		visited[i] = 0;
	for(int i=0;i<G.vexnum;i++)
	{
		if(!visited[i])
			DFS(G, i);
	}
	PrintDN(G);
}
void BFS(AMGraph G)
{
	int i, j;
	SqQueue Q;
	for (i = 0; i < G.vexnum; i++)
		visited[MAXNUM] = 0;
	InitQueue(&Q);
	for (i = 0; i < G.vexnum; i++)
	{
		if (!visited[i])
		{
			visited[i] = 1;
			printf("%d ", G.vexs[i]);
			EnQueue(&Q, i);
 
			while (!IsEmpty(&Q))
			{
				DeQueue(&Q, &i);
				for (j = 0; j < G.vexnum; j++)
				{
					if (!visited[j] && G.arcs[i][j] != 32767)
					{
						visited[j] = 1;
						printf("%d ", G.arcs[j]);
						EnQueue(&Q, j);
					}
				}
			}
		}
	}
}

完整代码如下

#include "iostream.h"
#include "stdio.h"
#include "stdlib.h"
#define MAXNUM 100
#define MAXInt 32767
#define OK   1
#define ERROR 0
#define TRUE   1
#define FALSE  0
#define MAXQSIZE  100  /*最大队列长度*/

typedef int Status;/*返回类型*/
typedef char VexType;/*顶点的数据类型*/
typedef int ArcType;/*边的权值类型*/
typedef int QElemType;/*队列基地址类型*/
/*typedef float AdjType; */
/*typedef char InfoType; */

/*图的邻接矩阵*/
typedef struct {
	VexType vexs[MAXNUM];/*顶点表*/
	ArcType arcs[MAXNUM][MAXNUM];/*邻接矩阵*/
	int vexnum, arcnum;	/*图的当前顶点数和边数*/
}AMGraph;

typedef struct ArcNode {
	int adjvex;          /* 该弧所指向的顶点的位置*/
	struct ArcNode *nextarc;   /* 指向下一条弧的指针*/
	/*AdjType weight;*/      /* 边的权,非带权图可以省略 */
	/*InfoType   *info;*/        /* 该弧相关信息的指针 可以省略*/
}ArcNode;

typedef struct VNode {
	VexType  data;            /* 顶点信息*/
	ArcNode  *firstarc;       /*指向第一条依附该顶点的指针*/
}VNode, AdjList[MAXNUM];

typedef struct {
	AdjList  vertices;
	int vexnum, arcnum;	/*图的当前顶点数和边数*/
}ALGraph;

int visited[MAXNUM];

typedef struct {
    QElemType  *data;  /* 存储空间基地址*/
    int  front;     /* 头指针,若队列不空,指向队列头元素*/
    int  rear;      /* 尾指针,若队列不空,指向队列尾元素 的下一个位置*/
}SqQueue;

/*确定两点在邻接矩阵G中的位置,即顶点数组的下标 */
Status LocateAMGVex(AMGraph G,char x){
	for(int i = 0; i < G.vexnum;i++){
		if(x == G.vexs[i]){
			return i;
		}
	}
	return -1;
}

/*确定两点在邻接表G中的位置,即顶点数组的下标 */
Status LocateALGVex(ALGraph G,char x){
	for(int i = 0; i < G.vexnum	;i++){
		if(x == G.vertices[i].data){
			return i;
		}
	}
	return -1;
}

/*邻接矩阵创建无权无向图*/
Status CreateUDNwom(AMGraph &G){
	char v1,v2;/*两顶点*/
	cout<<"请输入总顶点数和总边数:"<<endl;
	cin>>G.vexnum>>G.arcnum;/*输入总顶点数和总边数*/
	for(int i = 0;i < G.vexnum;i++){/*将各点输入顶点表中*/
		printf("请输入第%d个顶点:\n",i+1);	
		cin>>G.vexs[i];
	}
	for(int i = 0;i < G.vexnum;i++){
		for(int j = 0;j < G.vexnum;j++){/*初始化邻接矩阵,使之每个权值初始化为最大值*/
			G.arcs[i][j] = 0;
		}
	}
	for(int k = 0;k < G.arcnum;k++){
		printf("请输入第%d条边依附的顶点:\n",k+1);
		int i,j,w = 1;
		cin>>v1>>v2;/*输入一条边依附的顶点及其权值*/
		i = LocateAMGVex(G,v1);
		j = LocateAMGVex(G,v2);//确定两点在G中的位置,即顶点数组的下标 
		G.arcs[i][j] = w;/*给边赋值*/ 
		G.arcs[j][i] = w;/*置<v1,v2>的对称边<v2,v1>权值为w*/
	}
	return OK;
} 

/*邻接矩阵创建有权无向图*/
Status CreateUDNm(AMGraph &G){
	char v1,v2;/*两顶点*/
	cout<<"请输入总顶点数和总边数:"<<endl;
	cin>>G.vexnum>>G.arcnum;/*输入总顶点数和总边数*/
	for(int i = 0;i < G.vexnum;i++){/*将各点输入顶点表中*/
		printf("请输入第%d个顶点:\n",i+1);	
		cin>>G.vexs[i];
	}
	for(int i = 0;i < G.vexnum;i++){
		for(int j = 0;j < G.vexnum;j++){/*初始化邻接矩阵,使之每个权值初始化为最大值*/
			G.arcs[i][j] = MAXInt;
		}
	}
	for(int k = 0;k < G.arcnum;k++){
		printf("请输入第%d条边依附的顶点及其权值:\n",k+1);
		int i,j,w;/*权值*/
		cin>>v1>>v2>>w;/*输入一条边依附的顶点及其权值*/
		i = LocateAMGVex(G,v1);
		j = LocateAMGVex(G,v2);//确定两点在G中的位置,即顶点数组的下标 
		G.arcs[i][j] = w;/*给边赋值*/ 
		G.arcs[j][i] = w;/*置<v1,v2>的对称边<v2,v1>权值为w*/
	}
	return OK;
} 

/*邻接矩阵创建无权有向图*/
Status CreateDNwom(AMGraph &G){
	char v1,v2;/*两顶点*/
	cout<<"请输入总顶点数和总边数:"<<endl;
	cin>>G.vexnum>>G.arcnum;/*输入总顶点数和总边数*/
	for(int i = 0;i < G.vexnum;i++){/*将各点输入顶点表中*/
		printf("请输入第%d个顶点:\n",i+1);	
		cin>>G.vexs[i];
	}
	for(int i = 0;i < G.vexnum;i++){
		for(int j = 0;j < G.vexnum;j++){/*初始化邻接矩阵,使之每个权值初始化为最大值*/
			G.arcs[i][j] = 0;
		}
	}
	for(int k = 0;k < G.arcnum;k++){
		printf("请输入第%d条边依附的顶点:\n",k+1);
		int i,j,w = 1;
		cin>>v1>>v2;/*输入一条边依附的顶点及其权值*/
		i = LocateAMGVex(G,v1);
		j = LocateAMGVex(G,v2);//确定两点在G中的位置,即顶点数组的下标 
		G.arcs[i][j] = w;/*给边赋值*/ 
	}
	return OK;
}

/*邻接矩阵创建有权有向图*/
Status CreateDNm(AMGraph &G){
	char v1,v2;/*两顶点*/
	cout<<"请输入总顶点数和总边数:"<<endl;
	cin>>G.vexnum>>G.arcnum;/*输入总顶点数和总边数*/
	for(int i = 0;i < G.vexnum;i++){/*将各点输入顶点表中*/
		printf("请输入第%d个顶点:\n",i+1);	
		cin>>G.vexs[i];
	}
	for(int i = 0;i < G.vexnum;i++){
		for(int j = 0;j < G.vexnum;j++){/*初始化邻接矩阵,使之每个权值初始化为最大值*/
			G.arcs[i][j] = MAXInt;
		}
	}
	for(int k = 0;k < G.arcnum;k++){
		printf("请输入第%d条边依附的顶点及其权值:\n",k+1);
		int i,j,w;/*权值*/
		cin>>v1>>v2>>w;/*输入一条边依附的顶点及其权值*/
		i = LocateAMGVex(G,v1);
		j = LocateAMGVex(G,v2);//确定两点在G中的位置,即顶点数组的下标 
		G.arcs[i][j] = w;/*给边赋值*/ 
	}
	return OK;
}

/*打印邻接矩阵构造的图*/
void PrintN(AMGraph G){
	cout<<endl;
	for(int i = 0;i < G.vexnum;i++){
		for(int j = 0;j < G.vexnum;j++){
			printf("%5d  ",G.arcs[i][j]);
		}
		cout<<endl;
	}
	cout<<endl;
}

void InitQueue(SqQueue *Q)
{
	Q->front = Q->rear = 0;
}

Status IsEmpty(SqQueue *Q)
{
	if (Q->front == Q->rear)
		return 1;
	else
		return 0;
}
 
void EnQueue(SqQueue *Q,int e)
{
	if ((Q->rear + 1) % MAXNUM == Q->front)
		return;
	else
	{
		Q->data[Q->rear] = e;
		Q->rear = (Q->rear + 1) % MAXNUM;
	}
}

void DeQueue(SqQueue *Q,int *e)
{
	if (Q->rear == Q->front)
		return;
	*e = Q->data[Q->front];
	Q->front = (Q->front + 1) % MAXNUM;
}

Status  FirstVertex(ALGraph graph){
	if(graph.vexnum==0)
	   return -1;
	return 0;
}

Status  NextVertex(ALGraph graph,int v){
	if(v==graph.vexnum-1)
	   return -1;
	return v+1;
}

/* 边的插入*/
void insert(ALGraph* p,int a,int b){/*在图中插入边(a,b)*/
	ArcNode* pp;
	ArcNode* temp;
	temp=new ArcNode;
	temp->adjvex=b;
	temp->nextarc=NULL;
	pp=p->vertices[a].firstarc;
	if(pp==NULL)p->vertices[a].firstarc=temp;
	else{
		while(pp->nextarc!=NULL)
			pp=pp->nextarc;
		pp->nextarc=temp;
	}
}

/* 邻接表构造无向图*/
Status CreateUDG(ALGraph &G){
	char v1,v2;/*两顶点*/
	cout<<"请输入总顶点数(不超过100)和总边数:\n";
	cin>>G.vexnum>>G.arcnum;//输入总顶点数和总边数,-> cin可连续输入 
	for(int i=0;i<G.vexnum;i++){
		printf("请输入第%d个顶点:\n",i+1);
		cin>>G.vertices[i].data;		//输入顶点值 
		G.vertices[i].firstarc=NULL;	//初始化表头结点的指针域为NULL 
	}
	for(int k=0;k<G.arcnum;k++){
		int i,j;
		printf("请输入第%d条边依附的顶点:\n",k+1);
		cin>>v1>>v2;
		i = LocateALGVex(G,v1);
		j = LocateALGVex(G,v2);
		ArcNode *p1 = new ArcNode;//生成一个新的边结点*p1 
		p1->adjvex = j;
		p1->nextarc = G.vertices[i].firstarc;
		G.vertices[i].firstarc = p1;	/*将新结点*p1插入至顶点vi的边表头部*/
		
		ArcNode *p2 = new ArcNode;//生成一个新的边结点*p2 
		p2->adjvex = i;
		p2->nextarc = G.vertices[j].firstarc;
		G.vertices[j].firstarc = p2;		/*将新结点*p2插入至顶点vj的边表头部*/
	}
	return OK;
}

/* 邻接表构造有向图*/
Status CreateDG(ALGraph &G){
	char v1,v2;/*两顶点*/
	cout<<"请输入总顶点数(不超过100)和总边数:\n";
	cin>>G.vexnum>>G.arcnum;//输入总顶点数和总边数,-> cin可连续输入 
	for(int i=0;i<G.vexnum;i++){
		printf("请输入第%d个顶点:\n",i+1);
		cin>>G.vertices[i].data;		//输入顶点值 
		G.vertices[i].firstarc=NULL;	//初始化表头结点的指针域为NULL 
	}
	for(int k=0;k<G.arcnum;k++){
		int i,j;
		printf("请输入第%d条边依附的顶点:\n",k+1);
		cin>>v1>>v2;
		i = LocateALGVex(G,v1);
		j = LocateALGVex(G,v2);
		ArcNode *p1 = new ArcNode;//生成一个新的边结点*p1 
		p1->adjvex = j;
		p1->nextarc = G.vertices[i].firstarc;
		G.vertices[i].firstarc = p1;	/*将新结点*p1插入至顶点vi的边表头部*/
	}
	return OK;
}

/*打印邻接表构造的图*/
void PrintDN(ALGraph G){
	for (int i=0;i<G.vexnum;i++) {
		VNode temp = G.vertices[i];									//将G的顶点信息付给temp
		ArcNode *p = temp.firstarc;							  //将顶点信息temp中的边信息给p
		if (p ==  NULL){
			cout<<G.vertices[i].data;
			cout<<endl;
		}
		else {
			cout<<temp.data;
			while (p)
			{
				cout<<"->";
				cout<<p->adjvex;
				p = p->nextarc;
			}
		}
		cout<<endl;
	}
}

void DFS(ALGraph G, int i){
	visited[i] = 1;
	for(int j=0;j<G.vexnum;j++)
	{
		if(G.vertices[j].firstarc == NULL && !visited[j])
			DFS(G,j);
	}
}
void DFSTraverse(ALGraph G){ /*G可能为非连通图*/
	for(int i=0;i<G.vexnum;i++)
		visited[i] = 0;
	for(int i=0;i<G.vexnum;i++)
	{
		if(!visited[i])
			DFS(G, i);
	}
	PrintDN(G);
}

void BFS(AMGraph G)
{
	int i, j;
	SqQueue Q;
	for (i = 0; i < G.vexnum; i++)
		visited[MAXNUM] = 0;
	InitQueue(&Q);
	for (i = 0; i < G.vexnum; i++)
	{
		if (!visited[i])
		{
			visited[i] = 1;
			printf("%d ", G.vexs[i]);
			EnQueue(&Q, i);
 
			while (!IsEmpty(&Q))
			{
				DeQueue(&Q, &i);
				for (j = 0; j < G.vexnum; j++)
				{
					if (!visited[j] && G.arcs[i][j] != 32767)
					{
						visited[j] = 1;
						printf("%d ", G.arcs[j]);
						EnQueue(&Q, j);
					}
				}
			}
		}
	}
}

void Switcie(){
	AMGraph G1;
	AMGraph G2;
	AMGraph G3;
	AMGraph G4;
	ALGraph G5;
	ALGraph G6;
	int choice;
	while(1){
		cout<<"\n******************************选择******************************\n";
		cout<<"|1.邻接矩阵构造无权无向图	 2.邻接矩阵构造有权无向图    |\n";
		cout<<"|3.邻接矩阵构造无权有向图	 4.邻接矩阵构造有权有向图    |\n";
		cout<<"|5.邻接表构造无向图      	 6.邻接表构造有向图          |\n";
		cout<<"|7.深度优先遍历邻接表构造的图	 8.广度优先遍历邻接表构造的图|	\n";
		cout<<"请输入选项:";
		cin>>choice;
		switch(choice)
		{
			case 1:
					if(CreateUDNwom(G1) == 1){
						cout<<endl<<"邻接矩阵构造无权无向图完成!!!"<<endl;
						PrintN(G1);
					}
					system("pause");
					system("cls");
					Switcie();
			case 2:
					if(CreateUDNm(G2) == 1){
						cout<<endl<<"邻接矩阵构造有权无向图完成!!!"<<endl;
						PrintN(G2);
					}
					system("pause");
					system("cls");
					Switcie();
			case 3:
					if(CreateDNwom(G3) == 1){
						cout<<endl<<"邻接矩阵构造无权有向图完成!!!"<<endl;
						PrintN(G3);
					}
					system("pause");
					system("cls");
					Switcie();
			case 4:
					if(CreateDNm(G4) == 1){
						cout<<endl<<"邻接矩阵构造有权有向图完成!!!"<<endl;
						PrintN(G4);
					}
					system("pause");
					system("cls");
					Switcie();
			case 5:
					if(CreateUDG(G5) == 1){
						cout<<endl<<"邻接表构造无向图完成!!!"<<endl<<"以0作为头结点依次向下命名!!!"<<endl<<endl;
						PrintDN(G5);
					}
					system("pause");
					system("cls");
					Switcie();
			case 6:
					if(CreateDG(G6) == 1){
						cout<<endl<<"邻接表构造有向图完成!!!"<<endl<<"以0作为头结点依次向下命名!!!"<<endl<<endl;
						PrintDN(G6);
					}
					system("pause");
					system("cls");
					Switcie();
			case 7:
					if(CreateUDG(G5) == 1){
						cout<<endl<<"邻接表构造无向图完成!!!"<<endl<<"以0作为头结点依次向下命名!!!"<<endl<<"深度优先遍历如下:"<<endl;
						DFSTraverse(G5);
					}
					system("pause");
					system("cls");
					Switcie();
			case 8:
					if(CreateUDNm(G2) == 1){
						cout<<endl<<"广度优先遍历如下:"<<endl; 
						BFS(G2);
					}
					system("pause");
					system("cls");
					Switcie();
			default:
					cout<<"您所输入的选项有误!!!"<<endl;
					system("pause");
					system("cls");
					Switcie();
		}
	}
}

int main()
{
	Switcie();
	return 0;
}

以上解决1~4题

第5题

#include <stdio.h>
#include <stdlib.h>
#define VertexMax 20 
#define MaxInt 32767 

typedef char VertexType; 

typedef struct
{
	VertexType Vertex[VertexMax];
	int AdjMatrix[VertexMax][VertexMax];
	int vexnum,arcnum;
}AMGraph;

typedef struct
{
	VertexType adjvex;
	int lowcost;
}ShortEdge;

int LocateVex(AMGraph *G,VertexType v)
{
	int i;
	
	for(i=0;i<G->vexnum;i++)
	{
		if(v==G->Vertex[i])
		{
			return i; 
		} 
	 } 
	 
	 printf("No Such Vertex!\n");
	 return -1;
}

void CreateUDN(AMGraph *G)
{
	int i,j;

	printf("输入顶点个数和边数:\n");
	printf("顶点数 n="); 
	scanf("%d",&G->vexnum);
	printf("边  数 e="); 
	scanf("%d",&G->arcnum);
	printf("\n"); 
	
	printf("\n");
	
	printf("输入顶点元素(无需空格隔开):");
	scanf("%s",G->Vertex);
	printf("\n");

	for(i=0;i<G->vexnum;i++) 
	 for(j=0;j<G->vexnum;j++)
	    {
	    	G->AdjMatrix[i][j]=MaxInt;
		}
	
	 int n,m;
	 VertexType v1,v2;
	 int w;
	 
	 printf("请输入边的信息和权值(例:AB,15):\n");
	 for(i=0;i<G->arcnum;i++)
	 {
	 	printf("输入第%d条边信息及权值:",i+1);
	 	scanf(" %c%c,%d",&v1,&v2,&w);
	 	n=LocateVex(G,v1); 
	 	m=LocateVex(G,v2); 
	 	if(n==-1||m==-1)
		 {
		 	printf("NO This Vertex!\n");
		 	return;
		  } 
	
	   G->AdjMatrix[n][m]=w;
	   G->AdjMatrix[m][n]=w;
     } 
}

void print(AMGraph G)
{
	int i,j;
	printf("\n-------------------------------");
	printf("\n 邻接矩阵:\n\n"); 	
	
		printf("\t ");
		for(i=0;i<G.vexnum;i++)
		printf("\t%c",G.Vertex[i]);
		printf("\n");
		 
		for(i=0;i<G.vexnum;i++)
	   {
	   	  printf("\t%c",G.Vertex[i]);
	   	  
		  for(j=0;j<G.vexnum;j++)
	    {
	    	
	    	if(G.AdjMatrix[i][j]==MaxInt)
	 	    printf("\t∞");
	 	    else printf("\t%d",G.AdjMatrix[i][j]);
	    }
	      printf("\n");
	   }

	 
}

int minimal(AMGraph *G,ShortEdge *shortedge)
{
	int i,j;
	int min,loc;
	
	min=MaxInt;
	for(i=1;i<G->vexnum;i++)
	{
		if(min>shortedge[i].lowcost&&shortedge[i].lowcost!=0)
		{
			min=shortedge[i].lowcost;
			loc=i;
		}
	}
	return loc;
}
 
void MiniSpanTree_Prim(AMGraph *G,VertexType start)
{ 
	int i,j,k;
	ShortEdge shortedge[VertexMax];
	
	k=LocateVex(G,start);
	for(i=0;i<G->vexnum;i++)
	{
		shortedge[i].adjvex=start;
		shortedge[i].lowcost=G->AdjMatrix[k][i];
	}
	shortedge[k].lowcost=0;
	
	for(i=0;i<G->vexnum-1;i++)
	{
		k=minimal(G,shortedge);
	    printf("%c->%c,%d\n",shortedge[k].adjvex,G->Vertex[k],shortedge[k].lowcost);
	    shortedge[k].lowcost=0; 
	    
	    for(j=0;j<G->vexnum;j++)
	    {
	    	if(G->AdjMatrix[k][j]<shortedge[j].lowcost)
	    	{
	    		shortedge[j].lowcost=G->AdjMatrix[k][j];
	    		shortedge[j].adjvex=G->Vertex[k];
			}
		}
	 } 
}


int main() 
{
	VertexType start;
	AMGraph G;
	CreateUDN(&G);
	print(G); 
	
	printf("请输入起始点:");
	scanf(" %c",&start);
	MiniSpanTree_Prim(&G,start);
	return 0;
}

第6题

#include<cstdio>
using namespace std;
#define max 10000
#define inf 20000
int n,e;                           
int cost[20][20];	             
int dist[20];                     
int pre[20];                     
int S[20];                     
 
void Dijkstra(int v){
	for(int i=0;i<n;i++){
		dist[i]=cost[v][i];       
		S[i]=0;                  
		if(dist[i]<max)
			pre[i]=v;            
		else
			pre[i]=-1;            
	}
	S[0]=1;                       
	for(int i=0;i<n-1;i++){      
		int u;                     
		int min=inf;        
		for(int j=0;j<n;j++){
			if((!S[j])&&dist[j]<min){ 
				min=dist[j];
				u=j;
			}
		}
		S[u]=1;                    
		for(int k=0;k<n;k++){    
			if((!S[k])&&dist[k]>dist[u]+cost[u][k]){
				dist[k]=dist[u]+cost[u][k];
				pre[k]=u;        
			}
		}
	}
	printf("\nThe result:\n");    
	for(int i=0;i<n;i++){
		printf("<%d,%d>:  ",v+1,i+1);
		int p=pre[i];  
		if(p!=-1){                
			printf("%d  ",dist[i]);  
			printf("%d",i+1);     
			while(p!=v){
				printf("<--%d",p+1);
				p=pre[p];
			}
			printf("<--%d",v+1);
		}
		else{                     
			printf("inf");
		}
		printf("\n");
	}
}
 
int main(){
	printf("请输入顶点数和边数:");
	scanf("%d%d",&n,&e);
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
			cost[i][j]=max;      
	int start,end,dut;
	for(int i=0;i<e;i++){
		scanf("%d%d%d",&start,&end,&dut);     
		start--;
		end--;                     
		cost[start][end]=dut;
	}
	int v=0;
	Dijkstra(v);            
	return 0;
}

分享完毕~

欢迎小伙伴们在文下评论和私信喔~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jesonary

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值