方法一:DFS
template<class verType, class edgeType>
bool Graph<verType, edgeType>::circleJudge() const {
vector<bool> visited(verts, false); // 跟踪节点是否被访问过
vector<bool> recStack(verts, false); // 跟踪递归栈
for (int i = 0; i < verts; ++i) {
if (!visited[i]) // 如果节点未被访问过
if (isCyclicUtil(i, visited, recStack)) // 调用工具函数
return true;
}
return false;
}
template<class verType, class edgeType>
bool Graph<verType, edgeType>::isCyclicUtil(int v, vector<bool>& visited, vector<bool>& recStack) const {
if (!visited[v]) {
visited[v] = true; // 标记当前节点为已访问
recStack[v] = true; // 加入递归栈
// 遍历所有邻接点
for (int j = 0; j < verts; ++j) {
if (edgeMatrix[v][j] != noEdge) { // 如果存在边
if (!visited[j] && isCyclicUtil(j, visited, recStack)) // 递归访问邻接点
return true;
else if (recStack[j]) // 如果邻接点在递归栈中,存在环
return true;
}
}
}
recStack[v] = false; // 移除当前节点出递归栈
return false;
}
方法二:拓扑排序
template<class verType, class edgeType>
bool Graph<verType, edgeType>::circleJudge() const {
//计算所有结点的入度
bool InList[Vers];
for (int i = 0; i < Vers; i++)
{
InList[i] = false;
}
int InDegree[Vers];
for (int i = 0; i < Vers; i++){
for (int j = 0; j < Vers; j++){
if (edgeMatrix[i][j] != NoEdge) InDegree[j]++;
}
}
queue<int> q;
for (int i = 0; i < Vers; i++){
if (InDegree[i] == 0) q.push(i); //入度为0的结点入队
}
while (!q.empty())
{
int tmp = q.front();
q.pop();
Inlist[tmp] = true;
for (int k = 0; k < Vers; k++){
if (edgeMatrix[tmp][k] != NoEdge) {
if (--InDegree[k] == 0)
q.push(k);
}
}
}
for (int i = 0; i < Vers; i++)
if (InList[i] == false) return true;
return false;
}