• Dijkstra算法优先级队列版 算法基础篇(三)


    View Code
      1 // 优先队列的Dijkstra算法.cpp : 定义控制台应用程序的入口点。
      2 //
      3 
      4 #include "stdafx.h"
      5 #include <stdio.h>
      6 #include <queue>
      7 #include <vector>
      8 #include <stdlib.h>
      9 using namespace std;
     10 #define  NotAVertex (-1)
     11 #define  NumVertex 20
     12 #define  Infinity 1000
     13 typedef int Vertex;
     14 typedef int Arc;
     15 typedef int DistType;
     16 //typedef struct TableEntry* List;
     17 
     18 struct TableNode     //表节点
     19 {
     20     Vertex V;
     21     DistType Weigh;       //边重
     22     struct TableNode* NextArc;
     23 };
     24 
     25 typedef struct TableNode* EdgeNode;
     26 typedef struct ListNode* VexNode; //定义头节点指针
     27 struct ListNode     //头节点
     28 {
     29     Vertex V;
     30     EdgeNode FirstArc;
     31     DistType Dist;
     32     int  Known;
     33     Vertex Path;
     34 
     35     friend bool operator> ( struct ListNode n1,struct ListNode n2) //因为使用到greater模板 需要操作符>重载
     36     {
     37         return n1.Dist> n2.Dist;
     38     }
     39 
     40 };
     41 
     42 //typedef struct ListNode Node[NumVertex];
     43 typedef struct ListNode ListNode;
     44 priority_queue<ListNode,vector<ListNode>,greater<ListNode> > PriorVexQue; //申明优先级队列的类型 默认是less
     45 
     46 struct Graphic                 //图的结构体 包括有边数,点数,头节点数组
     47 {
     48     Vertex VertexNum;
     49     Arc    ArcNum;
     50     struct ListNode Adj[NumVertex];
     51 };
     52 
     53 typedef struct Graphic* Graph;
     54 
     55 void ReadGraph(Graph G)             //图的输入函数
     56 {
     57     Vertex from,to;
     58     DistType weight;
     59     struct TableNode *S;
     60     printf("请输入节点数和边数,注意为整型!\n");
     61     scanf("%d%d",&(G->VertexNum),&(G->ArcNum));
     62     if(G->ArcNum<=0||G->VertexNum<=0)
     63     {
     64         printf("图边数或点数必须大于零\n");
     65         return;
     66     }
     67     for(int i =0;i<G->ArcNum;i++)
     68     {
     69         printf("请输入第%d条边的起点,终点和权值!\n",i+1);
     70         scanf("%d%d%d",&from,&to,&weight);
     71         S=(EdgeNode)malloc(sizeof(struct TableNode));
     72         S->V=to;
     73         S->Weigh=weight;
     74         S->NextArc=G->Adj[from].FirstArc;       //这里是from的头边给S的下一条边,这里是表节点插入细节,好好体会下。
     75         G->Adj[from].FirstArc=S;
     76     }
     77 
     78 }
     79 
     80 void InitNode(Graph G)                     //图的初始化
     81 {
     82     int i ;
     83     for(i=0;i<NumVertex;i++)
     84     {
     85         G->Adj[i].V=i;
     86         G->Adj[i].Path=NotAVertex;
     87         G->Adj[i].Known=false;
     88         G->Adj[i].Dist=Infinity;
     89         G->Adj[i].FirstArc=NULL;
     90     }
     91     ReadGraph(G);
     92     G->Adj[0].Dist=0;
     93 }
     94 #if 0
     95 
     96 Vertex ExtractMin(Graph G)                              //较为简单的寻找最小值函数,复杂度O(n),一直不是很满意
     97 {
     98     int i;int j=Infinity;
     99     Vertex Min=Infinity;
    100     for(i=0;i<G->VertexNum;i++)
    101     {
    102         if(!(G->Adj[i].Known)&&Min>G->Adj[i].Dist)//刚开始犯了一个很傻的错误,这里的第二个条件放到第一个循环了,总是不对。
    103         {
    104             Min=G->Adj[i].Dist;
    105             j=i;
    106         }
    107     }
    108     if(j==Infinity) return -1;
    109     return j;
    110 }
    111 #endif
    112 
    113 
    114 
    115 void PrintPath(Graph G,Vertex V)             //打印分支函数,只能打印一条分支。
    116 {
    117     if(G->Adj[V].Path!=NotAVertex)
    118     {
    119         PrintPath(G,G->Adj[V].Path);
    120             printf("to");
    121     }
    122     printf("  %d  ",V);
    123 }
    124 
    125 
    126 
    127 void Dijkstra(Graph G)                      //函数::步步贪心,最终全体贪心
    128 {
    129     Vertex Value;
    130     EdgeNode pVex;
    131     PriorVexQue.push(G->Adj[0]);
    132     for(int i=0;i<G->VertexNum;i++)
    133     {
    134         Value=PriorVexQue.top().V;     //抽取图中最小距离的点,纳入{S}
    135         PriorVexQue.pop();
    136         if(Value==NotAVertex)
    137             break;
    138         G->Adj[Value].Known=true;
    139         pVex=G->Adj[Value].FirstArc;
    140     //    pEdge=pVex->NextArc;
    141         while(pVex!=NULL)                    //对图{Q-S}点的集合中与距离最小点毗邻的点做松弛操作
    142         {
    143             
    144             if(!(G->Adj[pVex->V].Known))     //邻接的节点更新
    145             {
    146                 if(G->Adj[Value].Dist+pVex->Weigh< G->Adj[pVex->V].Dist)
    147                 {
    148                     G->Adj[pVex->V].Dist=G->Adj[Value].Dist+pVex->Weigh;
    149                     G->Adj[pVex->V].Path=Value;
    150                 }
    151                 PriorVexQue.push(G->Adj[pVex->V]);
    152             }
    153             pVex=pVex->NextArc;
    154         }
    155     }
    156 }
    157 
    158 Vertex ReturnDistMax(Graph G) //这个函数是为了方便Print调用的,可以不要。
    159 {
    160     int i;
    161     Vertex key=0;
    162     DistType Max=0;
    163     for(i=0;i<G->VertexNum;i++)
    164         if(G->Adj[i].Dist>Max)
    165         {
    166             Max=G->Adj[i].Dist;
    167             key=i;
    168         }
    169         return key;
    170 
    171 
    172 }
    173 
    174 
    175 int _tmain(int argc, _TCHAR* argv[])
    176 {
    177     int i;
    178     Vertex V;
    179     Graph G=(Graph)malloc(sizeof(Graphic));
    180     InitNode(G);
    181     Dijkstra(G);
    182 //    PrintPath(G,4);
    183     printf("\n");
    184     for(i=0;i<G->VertexNum;i++)
    185     {
    186         printf("##  %d  ##",G->Adj[i].Dist);
    187         printf("##$  %d  $##",G->Adj[i].Path);
    188     }
    189 
    190     V=ReturnDistMax(G);
    191         
    192     PrintPath(G,V);
    193 
    194 
    195 
    196     return 0;
    197 }
  • 相关阅读:
    串口数据字节位的理解
    【转】arm-none-linux-gnueabi-gcc下载
    【转】网络排错全面详解
    【转】VMware虚拟机三种网络模式详解
    【转】vi编辑只读文档无法保存的解决办法
    【转】关于在linux下清屏的几种技巧
    【转】64位Ubuntu 16.04搭建嵌入式交叉编译环境arm-linux-gcc过程图解
    ELF文件
    UCOSII内核代码分析
    vmware安装win7提示No CD-ROM drive to use:GCDROM not loaded
  • 原文地址:https://www.cnblogs.com/cslave/p/2549131.html
Copyright © 2020-2023  润新知