《程序员面试金典》(第六版)习题:仅为记录一下以加强印象,不为商业用途,如有侵权请联系删除。以下源码和解释参考了书中源码以及解释。
这里采用广度优先搜索解决。
enum visitingStatus { visited, visiting, unvisited };
class graphNode
{
private:
visitingStatus visited;
int ID;
vector<graphNode*> adjacent;
public:
graphNode(int id=0)
{
visited = unvisited;
adjacent = vector<graphNode*>();
ID = id;
cout << "graphNode::ID="<<ID << endl;
}
void setVisitStatus(visitingStatus value)
{
visited = value;
}
visitingStatus getVisitStatus()
{
return visited;
}
int getID()
{
return ID;
}
bool operator==(graphNode& right)
{
return this->ID == right.getID();
}
vector<graphNode*> &getAdjacent()
{
cout << "graphNode::getAdjacent()" << endl;
return adjacent;
}
};
class Graph
{
private:
vector<graphNode*> nodes;
public:
Graph()
{
nodes = vector<graphNode*>();
}
vector<graphNode*>& getNodes()
{
cout << "Graph::getNodes()" << endl;
return nodes;
}
};
bool existingPath(Graph& g, graphNode* start, graphNode* end)
{
start->setVisitStatus(visiting);
if (*start == *end)
return true;
queue<graphNode*> temp = queue<graphNode*>();
temp.push(start);
graphNode* tempNode;
while (!temp.empty())
{
cout << "temp.size()="<<temp.size() << endl;
graphNode* tempNode2;
tempNode = temp.front();
temp.pop();
if (tempNode != nullptr)
{
int adjacentSize = tempNode->getAdjacent().size();
cout << "adjacentSize ="<< adjacentSize << endl;
if (adjacentSize != 0)
{
for (int index = 0; index < adjacentSize; index++)
{
tempNode2 = tempNode->getAdjacent()[index];
cout<< "tempNode2->getID()=" <<tempNode2->getID()<<endl;
if (tempNode2->getVisitStatus()==unvisited)
{
if (tempNode2 == end)
{
cout << "tempNode2 == end" << endl;
return true;
}
else
{
temp.push(tempNode2);
tempNode2->setVisitStatus(visiting);
cout << "temp.push(tempNode2)" << endl;
}
}
}
}
tempNode->setVisitStatus(visited);
}
}
return false;
}
一个简单的例子如图1所示,结果如图2所示。测试程序也示于下方。
int main()
{
Graph myGraph;
graphNode node0(0);
graphNode node1(1);
graphNode node2(2);
graphNode node3(3);
node0.getAdjacent().push_back(&node1);
node0.getAdjacent().push_back(&node2);
node1.getAdjacent().push_back(&node2);
node2.getAdjacent().push_back(&node3);
node3.getAdjacent().push_back(&node0);
myGraph.getNodes().push_back(&node0);
myGraph.getNodes().push_back(&node1);
myGraph.getNodes().push_back(&node2);
myGraph.getNodes().push_back(&node3);
if (existingPath(myGraph, &node0, &node3))
{
cout << "true";
}
else
{
cout << "false";
}
}