码迷,mamicode.com
首页 > 编程语言 > 详细

实用数据结构---图的操作和算法

时间:2015-03-12 22:38:07      阅读:309      评论:0      收藏:0      [点我收藏+]

标签:图算法   最小生成树   最短路径   dfs   bfs   

图算法的源代码、包含大量的注释,和最小生成树、最短路径、邻接表图深度广度优先搜索,邻接矩阵图深度广度优先搜索,欢迎借鉴

#include<stdio.h>
#include<stdlib.h>
#define MAXVEX 20
#define INFINITY 65535
typedef char vertexType;
typedef int edgeType;
typedef int Boolean;
typedef int Pathmatirx[MAXVEX];		//用于存储最短路径下标的数组
typedef int ShortPathTabl[MAXVEX];	//用于存数最短路径权值和的数组
Boolean visited[MAXVEX];
//图的邻接矩阵结构
typedef struct{
	vertexType vexs[MAXVEX];
	edgeType arc[MAXVEX][MAXVEX];
	int numVertexs, numEdges;
}Mgraph;

//邻接矩阵图的创建
void creatGraph(Mgraph *G){
	int i, j,k,w;
	printf("输入顶点数和边数\n");
	scanf_s("%d%d", &(G->numVertexs), &(G->numEdges));
	printf("输入顶点信息\n");
	getchar();
	for (i = 0; i < G->numVertexs; i++)
		scanf_s("%c", &(G->vexs[i]));
	//矩阵初始化
	for (i = 0; i < G->numVertexs;i++)
	for (j = 0; j < G->numVertexs; j++)
		G->arc[i][j] = INFINITY;
	printf("输入顶点上下标i,j和权重w\n");
	getchar();
	for (k = 0; k < G->numEdges; k++)
	{
		scanf_s("%d%d%d", &i, &j, &w);
		G->arc[i][j] = w;
		G->arc[j][i] = w;	//无向图,矩阵对称
	}
}

////顺序队列节点
//typedef struct{
//	char data[MAXVEX];
//	int front;
//	int rear;
//}Queue;
//
////初始化队列
//void InitQueue(Queue* q){
//	q->front = 0;
//	q->rear = 0;
//}
//
////返回队列长度
//int QueueLength(Queue *q){
//	return (q->rear - q->front + MAXVEX) % MAXVEX;
//}
//
////判断队列是否已满
//bool isFull(Queue *q){
//	if ((q->rear + 1) % MAXVEX == q->front)
//		return true;
//	else
//		return false;
//}
//
////入队列
//bool enQueue(Queue *q,char e){
//	if (!isFull(q)){
//		q->data[q->rear] = e;
//		q->rear = (q->rear+1) % MAXVEX;
//		return true;
//	}
//	else
//		return false;
//}
//
////出队列
//bool Dequeue(Queue *q, char *e){
//	if (q->front == q->rear)
//		return false;
//	*e = q->data[q->front];
//	q->front = (q->front + 1) % MAXVEX;
//	return true;
//}

////图的邻接表结构
//边节点
//typedef struct edgeNode{
//	int adjvex;		//当前点的下标
//	edgeType weight;
//	struct edgeNode *next;	//指向下一个邻接点
//}edgeNode;
//typedef struct vertexNode{
//	vertexType data;	//顶点数据域
//	struct edgeNode *firstEdge;
//}vertexNode,AdjList[MAXVEX];
//typedef struct{
//	AdjList adjList;
//	int numVertexes, numEdges;	//图中当前顶点数和边数
//}GraphAdjList;

//邻接表图的创建
//void creatGraph(GraphAdjList *g){
//	int i, j, k;
//	edgeNode *e;
//	printf("输入顶点数和边数\n");
//	scanf_s("%d%d", &g->numVertexes, &g->numEdges);
//	getchar();
//	for (i = 0; i < g->numVertexes; i++){
//		scanf_s("%c", &g->adjList[i].data);
//		g->adjList[i].firstEdge = NULL;
//	}
//	for (k = 0; k < g->numEdges; k++){
//		printf("输入边上的顶点序号\n");
//		scanf_s("%d%d", &i, &j);
//		e = (edgeNode*)malloc(sizeof(edgeNode));
//		e->adjvex = j;
//		e->next = g->adjList[i].firstEdge;
//		g->adjList[i].firstEdge = e;
//		e = (edgeNode*)malloc(sizeof(edgeNode));
//		e->adjvex = i;
//		e->next = g->adjList[j].firstEdge;
//		g->adjList[j].firstEdge = e;
//	}
//}

//邻接矩阵的深度优先算法
//void DFS(Mgraph *g,int i){
//	visited[i] = true;
//	printf("%c ", g->vexs[i]);
//	for (int j = 0; j < g->numVertexs; j++){
//		if (g->arc[i][j] == 1 && !visited[j])
//			DFS(g, j);
//	}
//}
//void DFSTraverse(Mgraph *g){
//	int i;
//	for (i = 0; i < g->numVertexs; i++)
//		visited[i] = false;
//	for (i = 0; i < g->numVertexs; i++){
//		if (!visited[i])
//			DFS(g, i);
//	}
//}
//邻接表的深度优先遍历算法
//void DFS(GraphAdjList *a,int i){
//	visited[i] = true;
//	edgeNode *p;
//	p = a->adjList[i].firstEdge;
//	printf("%c ", a->adjList[i].data);
//	while (p){
//		if (!visited[p->adjvex])
//			DFS(a, p->adjvex);
//		p = p->next;
//	}
//}
//void DFSTraverse(GraphAdjList *a){
//	int i;
//	for (i = 0; i < a->numVertexes; i++)
//		visited[i] = false;
//	for (i = 0; i < a->numVertexes; i++)
//	{
//		if (!visited[i])
//			DFS(a, i);
//	}
//}

//删除邻接表图
//void del(GraphAdjList *a, int i){
//	edgeNode *p;
//	visited[i] = true;
//	p = a->adjList[i].firstEdge->next;
//	free(a->adjList[i].firstEdge);
//	a->adjList[i].firstEdge->next = p->next;
//	while (p){
//		if (!visited[p->adjvex])
//			del(a, p->adjvex);
//		p = p->next;
//	}
//}
//void delGraph(GraphAdjList *a){
//	int i;
//	for (i = 0; i < a->numVertexes; i++){
//		if (!visited[i])
//			del(a, i);
//	}
//}

//邻接矩阵图的广度优先遍历
//void BFS(Mgraph G){
//	int i;
//	char e;
//	for (i = 0; i < G.numVertexs; i++)
//		visited[i] = false;
//	Queue p;
//	Queue *q = &p;
//	InitQueue(q);
//	for (i = 0; i < G.numVertexs; i++){
//		if (!visited[i]){
//			visited[i] = true;
//			enQueue(q, G.vexs[i]);
//			while (q->front != q->rear){
//				Dequeue(q, &e);
//				printf("%c ", e);
//				for (int j = 0; j < G.numVertexs; j++){
//					if (!visited[j] && G.arc[i][j] == 1){
//						visited[j] = true;
//						enQueue(q, G.vexs[j]);
//					}
//
//				}
//			}
//		}
//
//	}
//}


//prim最小生成树算法
void MinSpanTree_prim(Mgraph G){
	int min, i, j, k;
	int adjvex[MAXVEX];
	int lowcost[MAXVEX];
	lowcost[0] = 0;
	adjvex[0] = 0;
	for (i = 1; i < G.numVertexs; i++){
		lowcost[i] = G.arc[0][i];
		adjvex[i] = 0;
	}
	for (i = 1; i < G.numVertexs; i++){
		min = INFINITY;
		j = 1;
		k = 0;
		while (j < G.numVertexs){
			if (lowcost[j] != 0 && lowcost[j] < min){
				min = lowcost[j];
				k = j;
			}
			j++;
		}
		printf("(%d %d) ", adjvex[k], k);
		lowcost[k] = 0;
		for (j = 1; j < G.numVertexs; j++){
			if (lowcost[j] != 0 && G.arc[k][j] < lowcost[j]){
				lowcost[j] = G.arc[k][j];
				adjvex[j] = k;
			}
		}
	}
}
//void MinSpanTree_prim(Mgraph G){
//	int i, j, k, min;
//	int adjvex[MAXVEX];
//	int lowcost[MAXVEX];
//	lowcost[0] = 0;
//	adjvex[0] = 0;
//	for (i = 1; i < G.numVertexs; i++){
//		lowcost[i] = G.arc[0][i];
//		adjvex[i] = 0;
//	}
//	for (i = 1	; i < G.numVertexs; i++){
//		min = INFINITY;
//		k = 0;
//		j = 1;
//		while (j < G.numVertexs){
//			if (lowcost[j] != 0 && lowcost[j]<min){
//				min = lowcost[j];
//				k = j;
//			}
//			j++;
//		}
//		lowcost[k] = 0;
//		printf("(%d,%d)", adjvex[k], k);
//		for (j = 1; j < G.numVertexs; j++){
//			if (lowcost[j] != 0 && lowcost[j] > G.arc[k][j]){
//				lowcost[j] = G.arc[k][j];
//				adjvex[j] = k;
//			}
//		}
//	}
//}
//迪杰斯特拉

//迪杰斯特拉最短路径算法
//p[v]的值为前驱顶点下标,D[v]表示从v0到v最短路径长度和
void ShotestPath_Dijkstra(Mgraph G, int v0, Pathmatirx *P, ShortPathTabl *D){
	int v, w, k, min;
	int visited[MAXVEX];			//visited[i]=1表示求得v0到vi的最短路径
	for (v = 0; v < G.numVertexs; v++){
		visited[v] = 0;				//全部顶点初始化为未知最短路径状态
		(*D)[v] = G.arc[v0][v];		//将与v0点有连线的顶点加上权值
		(*P)[v] = 0;				//初始化路径数组p为0
	}
	(*D)[v0] = 0;					//v0到v0的路径为0
	visited[v0] = 1;				//v0到v0不需要求路径
	//开始主循环,每次求得v0到某个v的最短路径
	for (v = 1; v < G.numVertexs; v++){
		min = INFINITY;
		//寻找离v0最近的顶点
		for (w = 0; w < G.numVertexs; w++){
			if (!visited[w] && (*D)[w] < min){
				k = w;
				min = (*D)[w];		//w顶点离v0点更近
			}
		}
		visited[k] = 1;
		//修正当前最短路径及距离
		for (w = 0; w < G.numVertexs; w++){
			//如果经过v顶点的路径比现在这条路径的长度短的话
			if (!visited[w] && (min + G.arc[k][w]) < (*D)[w]){
				//说明找到了更短的路径,修正	D[w]和P[w]
				(*D)[w] = min + G.arc[k][w];
				(*P)[w] = k;
			}
		}
	}
}
//输出最小路径
void print(Pathmatirx *P,int n){
	if (n == 0){
		printf("0\n");
		return;
	}
	printf("%d<-", n);
	print(P, (*P)[n]);
}
int main(){
	Pathmatirx P[MAXVEX];
	ShortPathTabl D[MAXVEX];
	int v0 = 0;
	Mgraph G;
	creatGraph(&G);
	//MinSpanTree_prim(G);
	ShotestPath_Dijkstra(G, v0, P, D);
	print(P,8);
	system("pause");
	return 0;
}


实用数据结构---图的操作和算法

标签:图算法   最小生成树   最短路径   dfs   bfs   

原文地址:http://blog.csdn.net/u013174702/article/details/44227911

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!