圖之Dijkstra演算法

來源:互聯網
上載者:User

Dijkstra演算法是一種求單源最短路的演算法,即從一個點開始到所有其他點的最短路。其步驟如下:













c語言實現如下:(使用鄰接矩陣儲存)

#include <stdio.h>  #include <malloc.h>  #define VERTEXNUM 6  //存放最短路徑的邊元素typedef struct edge{        int vertex;int value;        struct edge* next;}st_edge;void createGraph(int (*edge)[VERTEXNUM], int start, int end, int value);  void displayGraph(int (*edge)[VERTEXNUM]); void displayPath(st_edge** path, int startVertex,int* shortestPath);void dijkstra(int (*edge)[VERTEXNUM], st_edge*** path, int** shortestPath, int startVertex, int* vertexStatusArr);int getDistance(int value, int startVertex, int start, int* shortestPath);void createPath(st_edge **path, int startVertex, int start, int end, int edgeValue);int main(void){  //動態建立存放邊的二維數組         int (*edge)[VERTEXNUM] = (int (*)[VERTEXNUM])malloc(sizeof(int)*VERTEXNUM*VERTEXNUM);          int i,j;          for(i=0;i<VERTEXNUM;i++){                  for(j=0;j<VERTEXNUM;j++){                          edge[i][j] = 0;                  }          }  //存放頂點的遍曆狀態,0:未遍曆,1:已遍曆        int* vertexStatusArr = (int*)malloc(sizeof(int)*VERTEXNUM);          for(i=0;i<VERTEXNUM;i++){                  vertexStatusArr[i] = 0;          }            printf("after init:\n");          displayGraph(edge);  //建立圖         createGraph(edge,0,1,6);          createGraph(edge,0,3,5);          createGraph(edge,0,2,1);          createGraph(edge,1,2,5);          createGraph(edge,1,4,3);          createGraph(edge,2,4,6);          createGraph(edge,2,3,5);          createGraph(edge,2,5,4);          createGraph(edge,3,5,2);          createGraph(edge,4,5,6);            printf("after create:\n");          displayGraph(edge);//最短路徑/*儲存的結構如下:path[0]:edge0->NULLpath[1]:edge1->NULLpath[2]:edge1->edge2->NULLpath[3]:edge1->edge2->edge3->NULLpath[4]:edge4->NULL從頂點0到0的最短路徑:從0出發直接到0從頂點0到1的最短路徑:從0出發直接到1從頂點0到2的最短路徑:從0出發到1,從1出發到2......*/st_edge** path = NULL;//儲存最短路徑的權值/*shortestPath[0] = 0;shortestPath[1] = 8;shortestPath[2] = 12;從頂點0到0的路徑是0從頂點0到1的路徑是8從頂點0到2的路徑是12*/int* shortestPath = NULL;//從頂點0開始尋找最短路徑int startVertex = 0;//最短路徑dijkstra(edge, &path, &shortestPath, startVertex, vertexStatusArr);printf("the path is:\n");displayPath(path,startVertex,shortestPath);          free(edge);          free(path);          return 0;  }  //建立圖 void createGraph(int (*edge)[VERTEXNUM], int start, int end, int value){          edge[start][end] = value;          edge[end][start] = value;  }  //列印儲存的圖void displayGraph(int (*edge)[VERTEXNUM]){          int i,j;          for(i=0;i<VERTEXNUM;i++){                  for(j=0;j<VERTEXNUM;j++){                          printf("%d ",edge[i][j]);                  }                  printf("\n");          }  }//列印最短路徑void displayPath(st_edge** path, int startVertex,int* shortestPath){        int i;        st_edge* p;        for(i=0;i<VERTEXNUM;i++){                printf("Path from %d to %d:",startVertex,i);                p = *(path+i);                while(p != NULL){                        printf("%d(%d) ",p->vertex,p->value);                        p = p->next;                }                printf("\n");printf("the count is:%d\n",shortestPath[i]);        }}//最短路徑void dijkstra(int (*edge)[VERTEXNUM], st_edge*** path, int** shortestPath, int startVertex, int* vertexStatusArr){//初始化最短路徑*path = (st_edge**)malloc(sizeof(st_edge*)*VERTEXNUM);        int i,j;    for(i=0;i<VERTEXNUM;i++){if(i == startVertex){st_edge* e = (st_edge*)malloc(sizeof(st_edge));e->vertex = startVertex;e->value = 0;e->next = NULL;(*path)[i] = e;}else{            (*path)[i] = NULL;}    }//初始化最短路徑的權值*shortestPath = (int *)malloc(sizeof(int)*VERTEXNUM);for(i=0;i<VERTEXNUM;i++){if(i == startVertex){(*shortestPath)[i] = 0;}else{(*shortestPath)[i] = -1;}}//從頂點0開始,則頂點0就是已訪問的 vertexStatusArr[startVertex] = 1;       int shortest, distance,start, end, edgeValue, vNum = 1;//如果還頂點還沒有訪問完        while(vNum < VERTEXNUM){                shortest = 9999;                  for(i=0;i<VERTEXNUM;i++){  //選擇已經訪問過的點                        if(vertexStatusArr[i] == 1){                                  for(j=0;j<VERTEXNUM;j++){  //選擇一個沒有訪問過的點                                          if(vertexStatusArr[j] == 0){  //選出一條value最小的邊                                                if(edge[i][j] != 0 && (distance = getDistance(edge[i][j], startVertex, i,  *shortestPath)) < shortest){                                                          shortest = distance;                                                          edgeValue = edge[i][j];start = i;                                                          end = j;                                                  }                                          }                                  }                          }                  }                  vNum++;  //將點設定為訪問過 vertexStatusArr[end] = 1;   //儲存最短路徑權值(*shortestPath)[end] = shortest;//儲存最短路徑createPath(*path, startVertex, start, end, edgeValue);         }  }//返回從startVertex到新的頂點的距離int getDistance(int value, int startVertex, int start, int* shortestPath){if(start == startVertex){return value;}else{return shortestPath[start] + value;}}//儲存最短路徑void createPath(st_edge **path, int startVertex, int start, int end, int edgeValue){if(start == startVertex){st_edge* newEdge = (st_edge*)malloc(sizeof(st_edge));newEdge->vertex = end;newEdge->value = edgeValue;newEdge->next = NULL;st_edge** p = path + end;while((*p) != NULL){p = &((*p)->next);}*p = newEdge;}else{st_edge** pCopySrc = path + start;st_edge** pCopyDes = path + end;st_edge* newEdge = NULL;while((*pCopySrc) != NULL){newEdge = (st_edge*)malloc(sizeof(st_edge));*newEdge = **pCopySrc;newEdge->next = NULL;*pCopyDes = newEdge;pCopySrc = &((*pCopySrc)->next);pCopyDes = &((*pCopyDes)->next);}newEdge = (st_edge*)malloc(sizeof(st_edge));newEdge->vertex = end;newEdge->value = edgeValue;newEdge->next = NULL;*pCopyDes = newEdge;}}

c語言實現如下:(使用鄰接表格儲存體)

#include <stdio.h>#include <malloc.h>#define VERTEXNUM 6//存放頂點的鄰接表元素//存放最短路徑的邊元素typedef struct edge{        int vertex;int value;        struct edge* next;}st_edge;void createGraph(st_edge** edge, int start, int end, int value);void displayGraph(st_edge** edge);void delGraph(st_edge** edge);void dijkstra(st_edge** edge, st_edge*** path, int** shortestPath, int startVertex, int* vertexStatusArr);void displayPath(st_edge** path, int startVertex,int* shortestPath);int getDistance(int value, int startVertex, int start, int* shortestPath);void createPath(st_edge **path, int startVertex, int start, int end, int edgeValue);int main(void){//動態建立存放邊的指標數組  st_edge** edge = (st_edge**)malloc(sizeof(st_edge*)*VERTEXNUM);int i;for(i=0;i<VERTEXNUM;i++){edge[i] = NULL;}//存放頂點的遍曆狀態,0:未遍曆,1:已遍曆int* vertexStatusArr = (int*)malloc(sizeof(int)*VERTEXNUM);for(i=0;i<VERTEXNUM;i++){vertexStatusArr[i] = 0;}printf("after init:\n");displayGraph(edge);//建立圖createGraph(edge,0,1,6);createGraph(edge,0,3,5);createGraph(edge,0,2,1);createGraph(edge,1,2,5);createGraph(edge,1,4,3);createGraph(edge,2,4,6);createGraph(edge,2,3,5);createGraph(edge,2,5,4);createGraph(edge,3,5,2);createGraph(edge,4,5,6);printf("after create:\n");displayGraph(edge);//最短路徑/*儲存的結構如下:path[0]:edge0->NULLpath[1]:edge1->NULLpath[2]:edge1->edge2->NULLpath[3]:edge1->edge2->edge3->NULLpath[4]:edge4->NULL從頂點0到0的最短路徑:從0出發直接到0從頂點0到1的最短路徑:從0出發直接到1從頂點0到2的最短路徑:從0出發到1,從1出發到2......*/st_edge** path = NULL;//儲存最短路徑的權值/*shortestPath[0] = 0;shortestPath[1] = 8;shortestPath[2] = 12;從頂點0到0的路徑是0從頂點0到1的路徑是8從頂點0到2的路徑是12*/int* shortestPath = NULL;int startVertex = 0;//最短路徑dijkstra(edge, &path, &shortestPath, startVertex, vertexStatusArr);printf("the path is:\n");displayPath(path,startVertex,shortestPath);delGraph(edge);edge = NULL;delGraph(path);path = NULL;if(vertexStatusArr != NULL){        free(vertexStatusArr);       vertexStatusArr = NULL;}if(shortestPath != NULL){free(shortestPath);shortestPath = NULL;}        return 0;}//建立圖void createGraph(st_edge** edge, int start, int end, int value){        st_edge* newedge1 = (st_edge*)malloc(sizeof(st_edge));        newedge1->vertex = end;newedge1->value = value;        newedge1->next = NULL;        st_edge** edge1 = edge + start;        while(*edge1 != NULL){                edge1 = &((*edge1)->next);        }        *edge1 = newedge1;st_edge* newedge2 = (st_edge*)malloc(sizeof(st_edge));        newedge2->vertex = start;        newedge2->value = value;        newedge2->next = NULL;        st_edge** edge2 = edge + end;        while(*edge2 != NULL){                edge2 = &((*edge2)->next);        }        *edge2 = newedge2;}//列印儲存的圖  void displayGraph(st_edge** edge){        int i;        st_edge* p;        for(i=0;i<VERTEXNUM;i++){                printf("%d:",i);                p = *(edge+i);                while(p != NULL){                        printf("%d(%d) ",p->vertex,p->value);                        p = p->next;                }                printf("\n");        }}//列印最短路徑void displayPath(st_edge** path, int startVertex,int* shortestPath){        int i;        st_edge* p;        for(i=0;i<VERTEXNUM;i++){                printf("Path from %d to %d:",startVertex,i);                p = *(path+i);                while(p != NULL){                        printf("%d(%d) ",p->vertex,p->value);                        p = p->next;                }                printf("\n");printf("the count is:%d\n",shortestPath[i]);        }}//釋放鄰接表佔用的記憶體void delGraph(st_edge** edge){        int i;        st_edge* p;        st_edge* del;        for(i=0;i<VERTEXNUM;i++){                p = *(edge+i);                while(p != NULL){                        del = p;                        p = p->next;                        free(del);                }                edge[i] = NULL;        }        free(edge);}//dijkstra求最短路徑void dijkstra(st_edge** edge, st_edge*** path, int** shortestPath, int startVertex, int* vertexStatusArr){//初始化最短路徑*path = (st_edge**)malloc(sizeof(st_edge*)*VERTEXNUM);        int i,j;        for(i=0;i<VERTEXNUM;i++){if(i == startVertex){st_edge* e = (st_edge*)malloc(sizeof(st_edge));e->vertex = startVertex;e->value = 0;e->next = NULL;(*path)[i] = e;}else{            (*path)[i] = NULL;}        }//初始化最短路徑的權值*shortestPath = (int *)malloc(sizeof(int)*VERTEXNUM);for(i=0;i<VERTEXNUM;i++){if(i == startVertex){(*shortestPath)[i] = 0;}else{(*shortestPath)[i] = -1;}}vertexStatusArr[startVertex] = 1;st_edge* p;int shortest, distance, edgeValue, start, end, vNum = 1;//如果還頂點還沒有訪問完while(vNum < VERTEXNUM){shortest = 9999;for(i=0;i<VERTEXNUM;i++){//選擇已經訪問過的點if(vertexStatusArr[i] == 1){for(j=0;j<VERTEXNUM;j++){//選擇一個沒有訪問過的點 if(vertexStatusArr[j] == 0){p = *(edge+i);while(p != NULL){//如果從startVertex到j的距離小於shortestif((distance = getDistance(p->value, startVertex, i, *shortestPath)) < shortest && p->vertex == j){shortest = distance;edgeValue = p->value;start = i;end = j;}p = p->next;}}}}}vNum++;vertexStatusArr[end] = 1;//儲存最短路徑的權值(*shortestPath)[end] = shortest;//儲存最短路徑createPath(*path, startVertex, start, end, edgeValue);}}//返回從startVertex到新的頂點的距離int getDistance(int value, int startVertex, int start, int* shortestPath){if(start == startVertex){return value;}else{return value + shortestPath[start];}}//儲存最短路徑void createPath(st_edge **path, int startVertex, int start, int end, int edgeValue){if(start == startVertex){st_edge* newEdge = (st_edge*)malloc(sizeof(st_edge));newEdge->vertex = end;newEdge->value = edgeValue;newEdge->next = NULL;st_edge** p = path + end;while((*p) != NULL){p = &((*p)->next);}*p = newEdge;}else{st_edge** pCopySrc = path + start;st_edge** pCopyDes = path + end;st_edge* newEdge = NULL;while((*pCopySrc) != NULL){newEdge = (st_edge*)malloc(sizeof(st_edge));*newEdge = **pCopySrc;newEdge->next = NULL;*pCopyDes = newEdge;pCopySrc = &((*pCopySrc)->next);pCopyDes = &((*pCopyDes)->next);}newEdge = (st_edge*)malloc(sizeof(st_edge));newEdge->vertex = end;newEdge->value = edgeValue;newEdge->next = NULL;*pCopyDes = newEdge;}}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.