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


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

    #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("输入顶点数和边数
    ");
    	scanf_s("%d%d", &(G->numVertexs), &(G->numEdges));
    	printf("输入顶点信息
    ");
    	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
    ");
    	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("输入顶点数和边数
    ");
    //	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("输入边上的顶点序号
    ");
    //		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
    ");
    		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;
    }


  • 相关阅读:
    csp-s 92
    支持smtp/imap smtp/pop3的撞库python撞库脚本
    关于KB2839299 微软补丁前后的kifastcallentry
    (转载)RegSetValueEx设置REG_SZ类型键值时要注意的问题
    x64windows安全机制进程_线程_模块加载回调摘要
    windbg脚本实践3----监控特定进程创建
    windbg脚本实践2----监控特定注册表键值创建和删除
    windbg脚本实践1----监控特定文件创建 删除 读写
    纪念在乙方安全公司的2年_关于杀毒软件和远控的斗争
    文件删除的windows下面的三种路径(轻量级)
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/6834845.html
Copyright © 2020-2023  润新知