数据结构有向加权图(采用邻接矩阵存储结构)

1题目:

元素类型:字符

存储结构:邻接矩阵

抽象数据类型:有向加权图

   ADT List{

           数据对象:D={ ai | ai∈ElemSet, i=1,2,...,n,  n≥0 }

           数据关系:R1={ <ai-1, ai>|ai-1, ai∈D, i=2,...,n }

           基本操作:

Status InitGraph(MGraph *G, VexType *vexs, int n);
//初始化含有N个顶点且无边的图

Status CreatGraph(MGraph *G, VexType *vex, int n, ArcInfo *arcs, int e);
//创建n个顶点和e条边的图,vexs为顶点信息,arcs为边信息

int LocateVex(MGraph G, VexType v);
//用来获取顶点的位置

VexType GetVex(MGraph G, int k);   //取图G的k顶点的值到w

Status PutVex(MGraph G, int k, VexType w);    
//对图G的k顶点赋值w

int FirstAdjVex(MGraph G, int k);       
//求图G中k顶点的第一个邻接顶点的位序

int NextAdjVex(MGraph G, int k, int m);   
//m顶点为k顶点到m顶点的边或者弧,求图中K顶点相对于m顶点的下一个邻接顶点的位序

Status AddArc(MGraph G, int k, int m, int info);   
//在图G中增加k到m的线,和权值

Status Remove(MGraph G, int k, int m);    //删除图中k到m的线

Status DFS(MGraph G, int k);  //连通图的深度优先遍历

Status DFSTraverse(MGraph G);  //完整图的优先遍历

LQueue* InitQueue();    //构造一个空队列

Status EnQueue(LQueue *Q, int e);  	//在队列的队尾插入

Status DeQueue(LQueue *Q, int *e);  	//是队列Q的队头出队并且返回到e

Status BFS(MGraph G, Status(*visit)(int));   //广度优先遍历 

} ADT List


#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR -1
#define OVERFLOW -1
typedef int Status;

#define UNVISITED 0
#define VISITED 1
#define INFINITY 65535   //取计算机允许的最大值,正无穷 

typedef char VexType;/* 元素类型为字符类型*/


/*有向加权图的邻接数组存取结构 */
typedef struct {
	VexType *vexs;     /*顶点数组,VexType是顶点类型,由用户定义*/
	int **arcs;        /*关系数组,对于有权图,它的值是权值或者INFINITY*/
	int n, e; 		   /*定义顶点数n和边数e*/
	int *tags;         /*标志数组,可用于在图的遍历中标记顶点访问与否*/
}MGraph;

/*弧线的存储结构*/
typedef struct {
	VexType v, w;     //边弧的端点 
	int info;       //边弧的权值 
}ArcInfo;

/*下列队列用来辅助图的遍历*/
/*定义队列的节点*/
typedef struct LQNode {
	int data;
	struct LQNode *next;
}LQNode, *QueuePtr;

/*定义队列*/
typedef struct {
	QueuePtr front;
	QueuePtr rear;
}LQueue;

Status InitGraph(MGraph *G, VexType *vexs, int n) {
	/*初始化含有N个顶点且无边的图*/
	int i, j;
	if (n < 0 || (n > 0 && vexs == NULL))  return ERROR;
	G->n = n;
	G->e = 0;
	if (0 == n) return OK;
	if (NULL == (G->vexs = (VexType*)malloc(n * sizeof(VexType))))
		return OVERFLOW;
	for (i = 0; i < G->n; i++) G->vexs[i] = vexs[i];
	if (NULL == (G->arcs = (int**)malloc(n * sizeof(int*))))
		return OVERFLOW;
	for (i = 0; i < n; i++) {
		if (NULL == (G->arcs[i] = (int*)malloc(n * sizeof(int))))
			return OVERFLOW;
	}
	if (NULL == (G->tags = (int*)malloc(n * sizeof(int))))  return OVERFLOW;
	for (i = 0; i < n; i++) {
		G->tags[i] = UNVISITED;
		for (j = 0; j < n; j++) {
			G->arcs[i][j] = INFINITY;
		}
	}
	return OK;
}

Status CreatGraph(MGraph *G, VexType *vex, int n, ArcInfo *arcs, int e) {
	//创建n个顶点和e条边的图,vexs为顶点信息,arcs为边信息
	int i, j, k;
	if (InitGraph(G, vex, n) != OK)  return ERROR;
	G->e = e;
	for (k = 0; k < G->e; k++) {
		i = LocateVex(*G, arcs[k].v);
		j = LocateVex(*G, arcs[k].w);
		if (i < 0 || j < 0)  return ERROR;
		G->arcs[i][j] = arcs[k].info;
	}
	return OK;
}

int LocateVex(MGraph G, VexType v) {
	//用于获取顶点的位置
	int i;
	for (i = 0; i < G.n; i++) {
		if (G.vexs[i] == v)  return i;
	}
	return ERROR;
}

VexType GetVex(MGraph G, int k) {
	//取图G的k顶点的值到w
	if (k<0 || k>G.e)          return;
	return  G.vexs[k];
}

Status PutVex(MGraph G, int k, VexType w) {
	//对图G的k顶点赋值w
	if (k<0 || k>G.e)          return ERROR;
	G.vexs[k] = w;
	return  OK;
}

int FirstAdjVex(MGraph G, int k) {
	int i;
	if (k < 0 || k >= G.n)		return ERROR;
	for (i = 0; i <G.n; i++) {
		if (G.arcs[k][i] != INFINITY) return i;
	}
	return ERROR;
}

int NextAdjVex(MGraph G, int k, int m) {
	m = m + 1;
	// //m顶点为k顶点到m顶点的边或者弧,求图中K顶点相对于m顶点的下一个邻接顶点的位序
	if (k < 0 || k >= G.n || m<0 || m >= G.n || m <= k)		return ERROR;
	for (; m<G.n; m++)
	{
		if (G.arcs[k][m] != INFINITY) return m;
	}
	return ERROR;
}

Status AddArc(MGraph G, int k, int m, int info) {
	//在图G中增加k到m的线,和权值
	if (k < 0 || k >= G.n || m < 0 || m >= G.n || m <= k)		return ERROR;
	if (G.arcs[k][m] == INFINITY)
	{
		G.arcs[k][m] = info;
	}
	else
		return ERROR;
}

Status Remove(MGraph G, int k, int m) {
	//删除图中k到m的线
	if (k < 0 || k >= G.n || m < 0 || m >= G.n || m <= k)		return ERROR;
	if (G.arcs[k][m] != INFINITY)
	{
		G.arcs[k][m] = INFINITY;
	}
	else
		return ERROR;
}

Status DFS(MGraph G, int k) {
	//连通图的深度优先遍历
	int i;
	if (k < 0 || k >= G.n) return ERROR;
	printf("%c", G.vexs[k]);
	G.tags[k] = VISITED;
	for (i = FirstAdjVex(G, k); i >= 0; i = NextAdjVex(G, k, i)) {
		if (UNVISITED == G.tags[i])
			if (ERROR == DFS(G, i))
				return ERROR;
	}
	return OK;
}

Status DFSTraverse(MGraph G) {
	//完整图的优先遍历
	int i = 0;
	for (i = 0; i < G.n; i++)  G.tags[i] = UNVISITED;
	for (i = 0; i < G.n; i++) {
		if (UNVISITED == G.tags[i])
			if (ERROR == DFS(G, i))   return ERROR;
	}
	return OK;
}

LQueue* InitQueue() {
	//构造一个空队列
	LQueue *Q = (LQueue *)malloc(sizeof(LQueue));
	if (Q == NULL) return ERROR;
	Q->front = NULL;
	Q->rear = NULL;
	return Q;
}

Status EnQueue(LQueue *Q, int e) {
	//在队列的队尾插入e
	LQNode *p;
	p = (LQNode*)malloc(sizeof(LQNode));
	if (p == NULL)  return ERROR;
	p->data = e;
	p->next = NULL;
	if (NULL == Q->front) {
		Q->front = p;
		Q->rear = p;
	}
	else
	{
		Q->rear->next = p;
		Q->rear = p;
	}
	return OK;
}

Status DeQueue(LQueue *Q, int *e) {
	//是队列Q的队头出队并且返回到e
	LQNode *p;
	if (NULL == Q->front) return ERROR;
	p = Q->front;
	*e = p->data;
	Q->front = p->next;
	if (Q->rear == p)  Q->rear = NULL;
	free(p);
	return OK;
}

Status BFS(MGraph G) {
	//广度优先遍历 
	int i, j, k;
	int *p_k = &k;
	LQueue *Q = InitQueue();
	for (i = 0; i < G.n; i++)   G.tags[i] = UNVISITED;
	for (i = 0; i < G.n; i++) {
		if (UNVISITED == G.tags[i]) {
			printf("%c", G.vexs[i]);
			G.tags[i] = VISITED;
			EnQueue(Q, i);
			while (DeQueue(Q, p_k) == OK)
			{
				for (j = FirstAdjVex(G, k); j >= 0; j = NextAdjVex(G, k, j))
					if (UNVISITED == G.tags[j] && j >= 0) {
						printf("%c", G.vexs[j]);
						G.tags[j] = VISITED;
						EnQueue(Q, j);
					}
			}
		}
	}
	return OK;
}


void main() {
	printf("有向加权图测试:\n");
	MGraph M;
	MGraph *p_M = &M;
	VexType vexs[5] = { 'A','C','R','F','E' };
	int n = 5;
	int k = 3;;
	ArcInfo *p = (ArcInfo*)malloc(3 * sizeof(ArcInfo));
	p[0].v = 'A';
	p[0].w = 'R';
	p[0].info = 32;
	p[1].w = 'F';
	p[1].v = 'A';
	p[1].info = 34;
	p[2].v = 'R';
	p[2].w = 'E';
	p[2].info = 45;
	VexType w = 'c';
	CreatGraph(p_M, vexs, n, p, 3);
	printf("图的顶点如下:\n");
	for (int s = 0; s < M.n; s++) {
		printf("\t\t%c", M.vexs[s]);
	}
	printf("\n图的关系如下:\n");
	int h, s;
	for (h = 0; h < M.n; h++) {
		printf("%c:", M.vexs[h]);
		for (s = 0; s < M.n; s++)
		{
			printf("%d\t\t", M.arcs[h][s]);
		}
		printf("\n");
	}

	printf("\n获取指定位置顶点元素的测试:\n 位标1的元素是:");
	w = GetVex(M, 1);
	printf("%c\n", w);
	printf("\n将指定元素放入指定位标测试(将k放到o号位):\n");
	PutVex(M, 0, 'K');
	for (int s = 0; s < M.n; s++) {
		printf("\t\t%c", M.vexs[s]);
	}
	printf("\n获取指定位标的第一个邻接点元素测试(0号位标的第一个邻接点):\n");
	int i = FirstAdjVex(M, 0);
	printf("%c\t下一个邻接点是:", M.vexs[i]);
	i = NextAdjVex(M, 0, 2);
	printf("%c\n", M.vexs[i]);

	printf("在1和2之间增加连线,并加权20:\n");
	AddArc(M, 1, 2, 20);
	for (h = 0; h < M.n; h++) {
		printf("%c:", M.vexs[h]);
		for (s = 0; s < M.n; s++)
		{
			printf("%d\t\t", M.arcs[h][s]);
		}
		printf("\n");
	}
	printf("深度优先遍历结果:\n");
	DFSTraverse(M, 0);
	printf("\n");
	printf("广度优先遍历结果:\n");
	BFS(M);
	printf("\n\n");

	printf("移除2号和4号之间的连线:\n");
	Remove(M, 2, 4);
	for (h = 0; h < M.n; h++) {
		printf("%c:", M.vexs[h]);
		for (s = 0; s < M.n; s++)
		{
			printf("%d\t\t", M.arcs[h][s]);
		}
		printf("\n");
	}
	system("pause");
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值