Dijkstra算法 算法基础篇(三)

View Code
  1 // Dijkstra算法.cpp : 定义控制台应用程序的入口点。
  2 //
  3 
  4 
  5 #include <stdio.h>
  6 #include <stdlib.h>
  7 #define  NotAVertex (-1)
  8 #define  NumVertex 20
  9 #define  Infinity 1000
 10 typedef int Vertex;
 11 typedef int Arc;
 12 typedef int DistType;
 13 
 14 struct TableNode     //表节点
 15 {
 16     Vertex V;
 17     DistType Weigh;       //边重
 18     struct TableNode* NextArc;
 19 };
 20 
 21 typedef struct TableNode* EdgeNode;
 22 
 23 struct ListNode     //头节点
 24 {
 25     Vertex V;
 26     EdgeNode FirstArc;
 27     DistType Dist;
 28     int  Known;
 29     Vertex Path;
 30 };
 31 typedef struct ListNode* VexNode; //定义头节点指针
 32 
 33 
 34 struct Graphic                 //图的结构体 包括有边数,点数,头节点数组
 35 {
 36     Vertex VertexNum;
 37     Arc    ArcNum;
 38     struct ListNode Adj[NumVertex];
 39 };
 40 
 41 typedef struct Graphic* Graph;
 42 
 43 void ReadGraph(Graph G)             //图的输入函数
 44 {
 45     Vertex from,to;
 46     DistType weight;
 47     struct TableNode *S;
 48     printf("请输入节点数和边数,注意为整型!\n");
 49     scanf("%d%d",&(G->VertexNum),&(G->ArcNum));
 50     if(G->ArcNum<=0||G->VertexNum<=0)
 51     {
 52         printf("图边数或点数必须大于零\n");
 53         return;
 54     }
 55     for(int i =0;i<G->ArcNum;i++)
 56     {
 57         printf("请输入第%d条边的起点,终点和权值!\n",i+1);
 58         scanf("%d%d%d",&from,&to,&weight);
 59         S=(EdgeNode)malloc(sizeof(struct TableNode));
 60         S->V=to;
 61         S->Weigh=weight;
 62         S->NextArc=G->Adj[from].FirstArc;       //这里是from的头边给S的下一条边,这里是表节点插入细节,好好体会下。
 63         G->Adj[from].FirstArc=S;
 64     }
 65 
 66 }
 67 
 68 void InitNode(Graph G)                     //图的初始化
 69 {
 70     int i ;
 71     for(i=0;i<NumVertex;i++)
 72     {
 73         G->Adj[i].V=i;
 74         G->Adj[i].Path=NotAVertex;
 75         G->Adj[i].Known=false;
 76         G->Adj[i].Dist=Infinity;
 77         G->Adj[i].FirstArc=NULL;
 78     }
 79     ReadGraph(G);
 80     G->Adj[0].Dist=0;
 81 }
 82 
 83 Vertex ExtractMin(Graph G)                              //较为简单的寻找最小值函数,复杂度O(n),一直不是很满意
 84 {
 85     int i;int j=Infinity;
 86     Vertex Min=Infinity;
 87     for(i=0;i<G->VertexNum;i++)
 88     {
 89         if(!(G->Adj[i].Known)&&Min>G->Adj[i].Dist)//刚开始犯了一个很傻的错误,这里的第二个条件放到第一个循环了,总是不对。
 90         {
 91             Min=G->Adj[i].Dist;
 92             j=i;
 93         }
 94     }
 95     if(j==Infinity) return -1;
 96     return j;
 97 }
 98 
 99 void PrintPath(Graph G,Vertex V)             //打印分支函数,只能打印一条分支。
100 {
101     if(G->Adj[V].Path!=NotAVertex)
102     {
103         PrintPath(G,G->Adj[V].Path);
104             printf("to");
105     }
106     printf("  %d  ",V);
107 }
108 
109 
110 
111 void Dijkstra(Graph G)                      //函数::步步贪心,最终全体贪心
112 {
113     Vertex Value;
114     EdgeNode pVex;
115     for(int i=0;i<G->VertexNum;i++)
116     {
117         Value=ExtractMin(G);                     //抽取图中最小距离的点,纳入{S}
118         if(Value==NotAVertex)
119             break;
120         G->Adj[Value].Known=true;
121         pVex=G->Adj[Value].FirstArc;
122     //    pEdge=pVex->NextArc;
123         while(pVex!=NULL)                    //对图{Q-S}点的集合中与距离最小点毗邻的点做松弛操作
124         {
125             if(!(G->Adj[pVex->V].Known))     //邻接的节点更新
126             {
127                 if(G->Adj[Value].Dist+pVex->Weigh< G->Adj[pVex->V].Dist)
128                 {
129                     G->Adj[pVex->V].Dist=G->Adj[Value].Dist+pVex->Weigh;
130                     G->Adj[pVex->V].Path=Value;
131                 }
132             }
133             pVex=pVex->NextArc;
134         }
135     }
136 }
137 
138 Vertex ReturnDistMax(Graph G) //这个函数是为了方便Print调用的,可以不要。
139 {
140     int i;
141     Vertex key=0;
142     DistType Max=0;
143     for(i=0;i<G->VertexNum;i++)
144         if(G->Adj[i].Dist>Max)
145         {
146             Max=G->Adj[i].Dist;
147             key=i;
148         }
149         return key;
150 
151 
152 }
153 
154 
155 int _tmain(int argc, _TCHAR* argv[])
156 {
157     int i;
158     Vertex V;
159     Graph G=(Graph)malloc(sizeof(Graphic));
160     InitNode(G);
161     Dijkstra(G);
162     printf("\n");
163     for(i=0;i<G->VertexNum;i++)
164     {
165         printf("##  %d  ##",G->Adj[i].Dist);
166 //        printf("##$  %d  $##",G->Adj[i].Path);
167     }
168 
169     V=ReturnDistMax(G);
170         
171  //   PrintPath(G,V);
172 
173 
174 
175     return 0;
176 }

posted on 2012-06-13 18:06  北冥茶花开  阅读(183)  评论(0编辑  收藏  举报

导航