图算法的源代码、包含大量的注释,和最小生成树、最短路径、邻接表图深度广度优先搜索,邻接矩阵图深度广度优先搜索,欢迎借鉴
#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; }
原文地址:http://blog.csdn.net/u013174702/article/details/44227911