zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    Java实现蓝桥杯模拟组织晚会
    Java实现蓝桥杯模拟组织晚会
    ffmpeg+rtsp+dss
    开发ffmpeg/live555常见问题错误及解决方法
    SxsTrace工具使用方法
    移植strace调试工具到arm平台
    Linux on Power 上的调试工具和技术
    使用 Strace 和 GDB 调试工具的乐趣
    自助Linux之问题诊断工具strace
    通用Makefile
  • 原文地址:https://www.cnblogs.com/cslave/p/2548295.html
Copyright © 2011-2022 走看看