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) && ( ' \0 ' == 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\n ", pcPath);
249         free(pcPath);
250         pcPath = NULL;
251     }
252     
253      return  0;

254 } 

转载于:https://www.cnblogs.com/GhostZCH/p/4321527.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值