zoukankan      html  css  js  c++  java
  • c++ 最短路两种算法

    最短路是个老问题了,大神们留下很多文档但是很多都是针对算法使用一些固定大小的数组进行数据存储在实际应用中受到限制,这里自己练习一下,主要用了一些c++的stl,减少了固定长度数组的依赖,换一种写法试图提高可读性。有兴趣的同学可以试着将map/set 换成 hash_set/hash_map 应该能获得更高的效率,对于稀疏表,内存还是能省不少的。

    参考文献:  http://www.cnblogs.com/hxsyl/p/3270401.html


      1 /************************************************************************/
      2 /*     尽量用简单快速好理解的方法完成图的最短路径                          */
      3 /************************************************************************/
      4 #include <stdio.h>
      5 #include <string.h>
      6 #include <malloc.h>
      7 
      8 #include <iostream>
      9 #include <sstream>
     10 #include <string>
     11 
     12 #include <set>
     13 #include <map>
     14 #include <vector>
     15 #include <queue>
     16 
     17 #include <algorithm>
     18 
     19 using namespace std;
     20 
     21 typedef size_t Index;
     22 
     23 // 使用整数比string快
     24 map<string, Index> g_mapNode;       // string -> index      
     25 map<Index, string> g_mapNodeIndex;  // index -> string     
     26 map<Index, set<Index> > g_mapLink;       // 邻接表
     27 
     28 inline bool IsNullString(const char* pcName)
     29 {
     30     return (NULL == pcName) && ('' == pcName[0]);
     31 }
     32 
     33 inline bool IsNodeExist(const string& strName)
     34 {
     35     return g_mapNode.end() != g_mapNode.find(strName);
     36 }
     37 
     38 bool FindPath1(Index uSource, Index uTarget, vector<Index>& vecRlst)
     39 {
     40     map<Index, size_t> mapDistence;
     41     map<Index, Index>  mapPath;
     42 
     43     // inistalize
     44     map<Index, set<Index> >::iterator iterInit = g_mapLink.begin();
     45     for (; iterInit != g_mapLink.end(); ++iterInit)
     46     {
     47         if (iterInit->second.count(uTarget) != 0)
     48         {
     49             mapDistence[iterInit->first] = 1;
     50             mapPath[iterInit->first] = uTarget;
     51         }
     52     }
     53 
     54     // find
     55     size_t uNodeNum = g_mapNode.size();
     56     for (size_t i = 0; i < uNodeNum; ++i)
     57     {
     58         for (size_t j = 0; j < uNodeNum; ++j)
     59         {
     60             if (g_mapLink.count(i) != 0 && g_mapLink[i].count(j) != 0// i - > j 是通的
     61             {
     62                 if (mapDistence.count(j) != 0  // j -> uTarget是通的
     63                     && (mapDistence.count(i) == 0  // i -> uTarget 不存在或者 比从 j走远
     64                         || (mapDistence[j] + 1 < mapDistence[i])))
     65                 {
     66                     mapDistence[i] = mapDistence[j] + 1// 更新距离 
     67                     mapPath[i] = j;                      // 更新下一跳地址
     68                 }
     69             }
     70         }    
     71     }
     72 
     73     // 不可到达
     74     if (mapDistence.count(uSource) == 0)
     75     {
     76         return false;
     77     }
     78 
     79     while (uSource != uTarget)
     80     {
     81         vecRlst.push_back(uSource);
     82         uSource = mapPath[uSource];
     83     }
     84     vecRlst.push_back(uSource);
     85 
     86     return true;
     87 }
     88 
     89 bool FindPath2(Index uSource, Index uTarget, vector<Index>& vecRlst)
     90 {
     91     map<Index, Index>  mapLastJump;
     92     queue<Index> queNodeQue;
     93 
     94     bool bIsFind = false;
     95     queNodeQue.push(uSource);
     96     while (!queNodeQue.empty() && !bIsFind)
     97     {
     98         Index uIdx = queNodeQue.front();
     99         queNodeQue.pop(); 
    100         if (g_mapLink.count(uIdx) == 0)
    101         {
    102             continue;
    103         }
    104 
    105         set<Index>::iterator iter = g_mapLink[uIdx].begin();
    106         for (; iter != g_mapLink[uIdx].end(); iter++)
    107         {
    108             if (mapLastJump.count(*iter) != 0)
    109             {
    110                 continue;
    111             }
    112 
    113             mapLastJump[*iter] = uIdx;
    114             if (*iter == uTarget)
    115             {
    116                 bIsFind = true;
    117                 break;
    118             }
    119             queNodeQue.push(*iter);
    120         }
    121     }
    122     
    123     if (!bIsFind)
    124     {
    125         return false;
    126     }
    127 
    128     while(uTarget != uSource)
    129     {
    130         vecRlst.push_back(uTarget);
    131         uTarget = mapLastJump[uTarget];
    132     }
    133     vecRlst.push_back(uSource);
    134 
    135     reverse(vecRlst.begin(), vecRlst.end());
    136 
    137     return true;
    138 }
    139 
    140 void cmdInitialize()
    141 {
    142     g_mapNode.clear();
    143     g_mapLink.clear();
    144 }
    145 
    146 bool cmdAddNode(const char *pcNode)
    147 {
    148     if (IsNullString(pcNode))
    149     {
    150         return false;
    151     }
    152     
    153     string strName(pcNode);
    154     if (IsNodeExist(strName))
    155     {
    156         return false;
    157     }
    158 
    159     Index uIndex = g_mapNode.size();
    160     g_mapNode[strName] = uIndex;
    161     g_mapNodeIndex[uIndex] = strName;
    162 
    163     return true;
    164 }
    165 
    166 bool cmdAddLink(const char *pcSource, const char *pcTarget)
    167 {
    168     if (IsNullString(pcSource) || IsNullString(pcTarget))
    169     {
    170         return false;
    171     }
    172 
    173     string strSource(pcSource);
    174     string strTarget(pcTarget);
    175 
    176     if (!IsNodeExist(strSource) || !IsNodeExist(strTarget) || strSource == strTarget)
    177     {
    178         return false;
    179     }
    180 
    181     g_mapLink[g_mapNode[strSource]].insert(g_mapNode[strTarget]);
    182     g_mapLink[g_mapNode[strTarget]].insert(g_mapNode[strSource]);
    183 
    184     return true;
    185 }
    186 
    187 bool cmdFindPath(const char *pcSource, const char *pcTarget, char **ppcRlstPath)
    188 {
    189     if (NULL == ppcRlstPath)
    190     {
    191         return false;
    192     }
    193     *ppcRlstPath = NULL;
    194 
    195     string strSource(pcSource);
    196     string strTarget(pcTarget);
    197         
    198     if (!IsNodeExist(strSource) || !IsNodeExist(strTarget) || strSource == strTarget)
    199     {
    200         return false
    201     }
    202 
    203     vector<Index> vecPath;
    204     //if(!FindPath1(g_mapNode[strSource], g_mapNode[strTarget], vecPath))
    205     if(!FindPath2(g_mapNode[strSource], g_mapNode[strTarget], vecPath))
    206     {
    207         return false;
    208     }
    209 
    210     string strOutPut;
    211     stringstream ssOutPut("");
    212     for (size_t u = 0; u < vecPath.size(); ++u)
    213     {
    214         ssOutPut << g_mapNodeIndex[vecPath[u]] << "->"
    215     }
    216     
    217     strOutPut = ssOutPut.str();
    218     strOutPut = strOutPut.substr(0, strOutPut.length() - 2);
    219 
    220     *ppcRlstPath = (char *)malloc(sizeof(char) * (strOutPut.length() + 1));
    221     if (NULL == *ppcRlstPath)
    222     {
    223         return false;
    224     }
    225 
    226     strcpy(*ppcRlstPath, strOutPut.c_str());
    227 
    228     return true;
    229 }
    230 
    231 int main()
    232 {
    233     cmdInitialize();
    234 
    235     cmdAddNode("A");
    236     cmdAddNode("B");
    237     cmdAddNode("C");
    238     cmdAddNode("D");
    239 
    240     cmdAddLink("A""B");
    241     cmdAddLink("B""C");
    242     cmdAddLink("C""D");
    243     cmdAddLink("B""D");
    244 
    245     char *pcPath = NULL;
    246     if (cmdFindPath("A""D", &pcPath))
    247     {
    248         printf("%s ", pcPath);
    249         free(pcPath);
    250         pcPath = NULL;
    251     }
    252     
    253     return 0;

    254 } 

  • 相关阅读:
    boot文件上传的坑
    页面前端获取时间和数据库获取时间差八个小时 CST
    springcloud 学习
    springcloud 的eureka服务
    ROWNUM()应用案例-实现一个拉链表
    python dict 常用操作
    【转】团队项目的Git分支管理规范
    Python中使用cx_Oracle调用Oracle存储过程
    【转载】ORACLE 物化视图
    C# 加密解密
  • 原文地址:https://www.cnblogs.com/GhostZCH/p/4321527.html
Copyright © 2011-2022 走看看