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 } 

posted @ 2015-03-08 12:37  Ghost_zhao  阅读(2645)  评论(0编辑  收藏  举报