Código ejecutable para el gráfico (creación, recorrido, árbol de expansión mínimo)

Código ejecutable para el gráfico (creación, recorrido, árbol de expansión mínimo)

Al aprender la estructura de datos, con el fin de simplificar el código, el maestro a menudo usa pseudocódigo para dar clases, incluidos muchos libros de texto que también usan pseudocódigo, por lo que creo que escribir un conjunto de códigos para las operaciones básicas de los gráficos es más útil para aprendiendo. (El grafo creado es un grafo no dirigido)

Deja de decir tonterías y ve al código.

#include <stdio.h>
#include <stdlib.h>

#define MAXSIZE 256
#define MAXEDGE 1000
#define INIFINITY 65535//极大值
#define Status int
#define OK 1
#define TRUE 1
#define FALSE 0
typedef int Boolean;//布尔类型
typedef char VerType;//顶点类型
typedef char ElemType;
Boolean visited[MAXSIZE];//访问标志数组
typedef struct ArcNode
{
    
    
	int adjvex;//弧尾下标
	int weight;//权重
	struct ArcNode *next;
} ArcNode;
typedef struct
{
    
    
	VerType data;//顶点
	ArcNode *FirstArc;//第一条边
} VNode, AdjList[MAXSIZE]; //邻接表
typedef struct
{
    
    
	int vexnum;//顶点数
	int arcnum;//边数
	AdjList vertices;//邻接表数组
} ALGraph;
typedef struct
{
    
    
	int begin;
	int end;
	int weight;
} Edge;//边集数组
typedef struct QNode
{
    
    
	ElemType data;
	struct QNode *next;
} QNode, *QueuePtr;
typedef struct
{
    
    
	QueuePtr front;
	QueuePtr rear;
} LinkQueue; //队列

void InitQueue(LinkQueue *Q);//初始化队列
void EnQueue(LinkQueue *Q, ElemType e);//入队列操作
void DeleteQueue(LinkQueue *Q, int *e);//出队列操作
int EmptyQueue(LinkQueue Q);//判断队列是否为空
int LocateVex(ALGraph *G, VerType V);//找到V在邻接表中的下标
void CreatALGraph(ALGraph *G);//创建图
void DFS(ALGraph G, int i);//深度优先遍历
void DFSTraverse(ALGraph G);
void BFSTraverse(ALGraph G);//广度优先遍历
int getweight(ALGraph G, int start, int end);//找到权重
void MiniSpanTree_Prim(ALGraph G);//Prim算法
Edge *get_edges(ALGraph G);//获取边集数组
void Edges_sort(int  len, Edge *edges);//边集数组排序
int Find(int *parent, int f);
void MiniSpanTree_Kruskal(ALGraph G);//Kruskal算法

int main()
{
    
    
	ALGraph G;
	CreatALGraph(&G);
	//MiniSpanTree_Kruskal(G);
	//BFSTraverse(G);
	//DFSTraverse(G);
	return 0;
}




void InitQueue(LinkQueue *Q)//初始化一个空队列
{
    
    
	Q->front = Q->rear = (QueuePtr)malloc(sizeof(QNode));
	if(!Q->front)
	{
    
    
		exit(0);
	}
	else
	{
    
    
		Q->front->next = NULL;
	}
}
void EnQueue(LinkQueue *Q, ElemType e)//入队列操作
{
    
    
	QueuePtr p;
	p = (QueuePtr)malloc(sizeof(QNode));
	if(p == NULL)
	{
    
    
		exit(0);
	}
	p->data = e;
	p->next = NULL;
	Q->rear ->next = p;
	Q->rear = p;
}
void DeleteQueue(LinkQueue *Q, int *e)//出队列操作
{
    
    
	QueuePtr p;
	if(Q->front == Q->rear)
	{
    
    
		return ;
	}
	p = Q->front->next;
	*e = p->data;
	Q->front->next = p->next;
	if(Q->rear == p)
	{
    
    
		Q->rear = Q->front;
	}
	free(p);
}

int EmptyQueue(LinkQueue Q)
{
    
    
	return (Q.front == Q.rear ? 1 : 0);
}

int LocateVex(ALGraph *G, VerType V)
{
    
    
	int i;
	for(i = 0; i < G->vexnum; i++)
	{
    
    
		if(V == G->vertices[i].data)
			break;
	}
	return i;
}
void CreatALGraph(ALGraph *G)//创建无向图
{
    
    
	printf("请输入顶点个数\n");
	scanf("%d", &G->vexnum);
	printf("请输入边的个数\n");
	scanf("%d", &G->arcnum);
	fflush(stdin);
	for(int i = 0; i < G->vexnum; i++)
	{
    
    
		scanf("%c", &G->vertices[i].data);
		G->vertices[i].FirstArc = NULL;
	}
	fflush(stdin);
	for(int k = 0; k < G->arcnum; k++)
	{
    
    
		char V1, V2;
		int w;
		scanf("%c%c%d", &V1, &V2, &w);
		fflush(stdin);
		int i = LocateVex(G, V1);
		int j = LocateVex(G, V2);
		ArcNode *e = (ArcNode*)malloc(sizeof(ArcNode));
		e->weight = w;
		e->adjvex = j;
		e->next = G->vertices[i].FirstArc;
		G->vertices[i].FirstArc = e;
		ArcNode *t = (ArcNode*)malloc(sizeof(ArcNode));
		t->weight = w;
		t->adjvex = i;
		t->next = G->vertices[j].FirstArc;
		G->vertices[j].FirstArc = t;
	}
}

//深度优先遍历
void DFS(ALGraph G, int i)
{
    
    
	ArcNode *p;
	visited[i] = TRUE;
	printf("%c ", G.vertices[i].data);
	p = G.vertices[i].FirstArc;
	while(p)
	{
    
    
		if(visited[p->adjvex] != TRUE)
		{
    
    
			DFS(G, p->adjvex);
		}
		p = p->next;
	}
}

void DFSTraverse(ALGraph G)
{
    
    
	for(int i = 0; i < G.vexnum; i++)
	{
    
    
		visited[i] = FALSE;
	}
	for(int i = 0; i < G.vexnum; i++)
	{
    
    
		if(!visited[i])
		{
    
    
			DFS(G, i);
		}
	}
}


void BFSTraverse(ALGraph G)//广度优先遍历
{
    
    
	int i, j;
	ArcNode*p;
	LinkQueue Q;
	InitQueue(&Q);
	for(i = 0; i < G.vexnum; i++)
	{
    
    
		visited[i] = FALSE;
	}
	for(i = 0; i < G.vexnum; i++)
	{
    
    
		if(!visited[i])
		{
    
    
			printf("%c ", G.vertices[i].data);
			visited[i] = TRUE;
			EnQueue(&Q, i);
			while(!EmptyQueue(Q))
			{
    
    
				DeleteQueue(&Q, &j);
				p = G.vertices[j].FirstArc;
				while(p)
				{
    
    
					if(!visited[p->adjvex])
					{
    
    
						printf("%c ", G.vertices[p->adjvex].data);
						visited[p->adjvex] = TRUE;
						EnQueue(&Q, p->adjvex);
					}
					p = p->next;
				}
			}
		}
	}
}

//最小生成树prim算法
int getweight(ALGraph G, int start, int end)
{
    
    
	ArcNode *p;
	p = G.vertices[start].FirstArc;
	if(start == end)
	{
    
    
		return 0;
	}
	else
	{
    
    
		while(p)
		{
    
    
			if(end == p->adjvex)
			{
    
    
				return p->weight;
			}
			p = p->next;
		}
		return INIFINITY;
	}
}

void MiniSpanTree_Prim(ALGraph G)//prim算法
{
    
    
	int min, i, j, k;
	int weight;
	int adjvex[MAXSIZE];
	int lowcost[MAXSIZE];
	lowcost[0] = 0;
	adjvex[0] = 0;
	//初始化操作
	for(int i = 0; i < G.vexnum; i++)
	{
    
    
		lowcost[i] = getweight(G, 0, i);
		adjvex[i] = 0;
	}
	//构造最小生成树
	for(i = 1; i < G.vexnum; i++)
	{
    
    
		min = INIFINITY;
		j = 1;
		k = 0;
		//遍历全部顶点
		while(j < G.vexnum)
		{
    
    
			if(lowcost[j] != 0 && lowcost[j] < min)
			{
    
    
				min = lowcost[j];
				k = j;
			}
			j++;
		}
		printf("(%c,%c)\n", G.vertices[adjvex[k]].data, G.vertices[k].data); //打印当前顶点中权值最小的
		lowcost[k] = 0;
		for(j = 1; j < G.vexnum; j++)
		{
    
    
			weight = getweight(G, k, j);
			if(lowcost[j] != 0 && weight < lowcost[j])
			{
    
    
				lowcost[j] = weight;
				adjvex[j] = k;
			}
		}
	}
}
Edge *get_edges(ALGraph G)//获取边集数组
{
    
    
	int i, j;
	int index = 0;
	Edge *edges = (Edge*)malloc(G.arcnum * sizeof(Edge));
	for(i = 0; i < G.arcnum; i++)
	{
    
    
		ArcNode*p = G.vertices[i].FirstArc;
		while(p)
		{
    
    
			j = p->adjvex;
			if(i < j)
			{
    
    
				edges[index].begin = i;
				edges[index].end = j;
				edges[index].weight = p->weight;
				index++;
			}
			p = p->next;
		}
	}
	return edges;
}
void Edges_sort(int  len, Edge *edges) //边集数组的排序
{
    
    
	int i, j;
	for(i = 0; i < len - 1; i++)
	{
    
    
		for(j = 0; j < len - 1 - i; j++)
		{
    
    
			if(edges[j].weight > edges[j + 1].weight)
			{
    
    
				Edge temp;
				temp = edges[j];
				edges[j] = edges[j];
				edges[j]  = temp;
			}
		}
	}
}
int Find(int *parent, int f)
{
    
    
	while(parent[f] > 0)
	{
    
    
		f = parent[f];
	}
	return f;
}
void MiniSpanTree_Kruskal(ALGraph G)
{
    
    
	int i, n, m;
	Edge *edges = get_edges(G);//边集数组
	Edges_sort(G.arcnum, edges);
	int parent[MAXSIZE];
	for(i = 0; i < G.vexnum; i++)
	{
    
    
		parent[i] = 0;
	}
	for(i = 0; i < G.arcnum; i++)
	{
    
    
		n = Find(parent, edges[i].begin);
		m = Find(parent, edges[i].end);
		if(n != m)
		{
    
    
			parent[n] = m;
			printf("(%d,%d),%d\n", edges[i].begin, edges[i].end, edges[i].weight);
		}
	}
}

Supongo que te gusta

Origin blog.csdn.net/BWQ2019/article/details/106133781
Recomendado
Clasificación