下面该代码是对dijkstra算法的实现:
#ifndef __CDIJKSTRA__H #define __CDIJKSTRA__H #include <iostream> #include <string> #include <vector> //dijkstra 算法 仅针无负权有向图 const int NERVER_ATTACH = 9999; struct AdjacencyNode // 邻接点 含加权 { struct VertexNode* pNode; int nWeight; // 加权值 }; struct VertexNode // 顶点 { std::string cName; // 顶点名字 int nInDegree; // 入度 int nDistance; // 最短路径 std::vector<struct AdjacencyNode> vectNodes; // 邻接点 VertexNode() { cName = ""; nInDegree = NERVER_ATTACH; // 未分配的顶点 nDistance = NERVER_ATTACH; vectNodes.clear(); } }; class CDijkstra { public: CDijkstra(int nNodes); ~CDijkstra(); public: bool InsertEdge(std::string aIn, std::string bOut, int nWeight); // 插入有向边 aIn-->aOut 及加权 void Dijkstra(std::string sVertex); // 查找顶点strNode到所有顶点的最短路径 private: void FindIndexInsert(std::string aIn, int& nInsertIndex, bool& bFindInsert, bool& bFindIn); private: struct VertexNode* m_pNodes; // 所有顶点的集合 int m_nNodes; // 顶点数量 }; #endif #include "Dijkstra.h" #include <queue> CDijkstra::CDijkstra(int nNodes) : m_nNodes(nNodes) { m_pNodes = new struct VertexNode[nNodes]; } CDijkstra::~CDijkstra() { delete[] m_pNodes; } void CDijkstra::FindIndexInsert(std::string aIn, int& nInsertIndex, bool& bFindInsert, bool& bFindIn) { nInsertIndex = 0; bFindInsert = false; bFindIn = false; for (int i = 0; i < m_nNodes; i++) { if ((m_pNodes + i)->cName != aIn && (m_pNodes + i)->nInDegree == NERVER_ATTACH && !bFindInsert) { nInsertIndex = i; bFindInsert = true; } if ((m_pNodes + i)->cName == aIn) { bFindIn = true; nInsertIndex = i; break; } } } bool CDijkstra::InsertEdge(std::string aIn, std::string bOut, int nWeight) { int nInsertIndex = 0; bool bFindInsert = false; bool bFindIn = false; int nInsertIndexOut = 0; bool bFindInsertOut = false; bool bFindInOut = false; FindIndexInsert(aIn, nInsertIndex, bFindInsert, bFindIn); if (bFindInsert && !bFindIn) // 还未分配 { (m_pNodes + nInsertIndex)->cName = aIn; (m_pNodes + nInsertIndex)->nInDegree = 0; // 入度为0 } FindIndexInsert(bOut, nInsertIndexOut, bFindInsertOut, bFindInOut); if (bFindInsertOut && !bFindInOut) // 还未分配 { (m_pNodes + nInsertIndexOut)->cName = bOut; (m_pNodes + nInsertIndexOut)->nInDegree = 0; // 入度为0 } (m_pNodes + nInsertIndexOut)->nInDegree += 1; // 入度加1 struct AdjacencyNode objNode; objNode.nWeight = nWeight; objNode.pNode = m_pNodes + nInsertIndexOut; (m_pNodes + nInsertIndex)->vectNodes.push_back(objNode); // 改变邻接表 return true; } void CDijkstra::Dijkstra(std::string sVertex) { int nInsertIndex = 0; bool bFindInsert = false; bool bFindIn = false; FindIndexInsert(sVertex, nInsertIndex, bFindInsert, bFindIn); if (!bFindIn) // 没有该顶点 return; for (int i = 0; i < m_nNodes; i++) // 初始化到所有顶点的路径长度 (m_pNodes + i)->nDistance = NERVER_ATTACH; //unknow (m_pNodes + nInsertIndex)->nDistance = 0; // 自己到自己的路径为0 std::queue<struct VertexNode*> queueNode; queueNode.push(m_pNodes + nInsertIndex); while (!queueNode.empty()) { VertexNode* pNode = queueNode.front(); queueNode.pop(); if (!pNode->vectNodes.empty()) // 是否有邻接点 { for (auto iter = pNode->vectNodes.begin(); iter != pNode->vectNodes.end(); iter++) { if (iter->pNode->nDistance == NERVER_ATTACH) // 更新 { iter->pNode->nDistance = pNode->nDistance + iter->nWeight; queueNode.push(iter->pNode); } else if (iter->nWeight + pNode->nDistance < iter->pNode->nDistance) { iter->pNode->nDistance = iter->nWeight + pNode->nDistance; queueNode.push(iter->pNode); } } } } // 打印最短路径 for (int i = 0; i < m_nNodes; i++) { std::cout << sVertex << " 到顶点" << (m_pNodes + i)->cName << "的最短距离为: "; if ((m_pNodes + i)->nDistance == NERVER_ATTACH) std::cout << "无法到达" << std::endl; else std::cout << (m_pNodes + i)->nDistance << std::endl; } } #include "Dijkstra.h" int main() { CDijkstra objDijstra(7); objDijstra.InsertEdge("v1", "v2", 2); objDijstra.InsertEdge("v1", "v4", 1); objDijstra.InsertEdge("v2", "v4", 3); objDijstra.InsertEdge("v2", "v5", 10); objDijstra.InsertEdge("v3", "v6", 5); objDijstra.InsertEdge("v3", "v1", 4); objDijstra.InsertEdge("v4", "v3", 2); objDijstra.InsertEdge("v4", "v5", 2); objDijstra.InsertEdge("v4", "v6", 8); objDijstra.InsertEdge("v4", "v7", 4); objDijstra.InsertEdge("v5", "v7", 6); objDijstra.InsertEdge("v7", "v6", 1); objDijstra.Dijkstra("v1"); std::cin.get(); return 0; }