
**例如:**现在要找东西,假设有三个抽屉,东西在哪个抽屉不清楚,现在要将其找到,广度优先遍历的做法是:

思考:如何防止节点被重复遍历?
void BFS(const V& src)
{
size_t srci = GetVertexIndex(src);
queue<int> q;
vector<bool> visited(_vertexs.size(), false); // 标记数组
q.push(srci);
visited[srci] = true;
int levelSize = 1; // 控制每层出的数量
while (!q.empty())
{
// 一层一层出
for (size_t i = 0; i < levelSize; i++)
{
int front = q.front();
q.pop();
cout << front << ":" << _vertexs[front] << " ";
// 把front的邻接顶点入队列
for (size_t j = 0; j < _vertexs.size(); j++)
{
if (_matrix[front][j] != MAX_W && visited[j] == false)
{
q.push(j);
visited[j] = true;
}
}
}
cout << endl;
levelSize = q.size();
}
}

void _DFS(size_t srci, vector<bool>& visited)
{
cout << srci << ":" << _vertexs[srci] << endl;
visited[srci] = true;
for (size_t i = 0; i < _vertexs.size(); i++)
{
if (_matrix[i] != MAX_W && visited[i] == false)
{
_DFS(i, visited);
}
}
}
void DFS(const V& src)
{
size_t srci = GetVertexIndex(src);
vector<bool> visited(_vertexs.size(), false);
_DFS(srci, visited);
// 处理存在不连通的情况
for (size_t i = 0; i < _vertexs.size(); i++)
{
if (!visited[i])
{
_DFS(i, visited);
}
}
}

W Kruskal(Self& minTree)
{
size_t n = _vertexs.size();
// 初始化minTree
minTree._vertexs = _vertexs;
minTree._indexMap = _indexMap;
minTree._matrix.resize(n);
for (size_t i = 0; i < n; i++)
{
minTree._matrix[i].resize(n, MAX_W);
}
priority_queue<Edge, vector<Edge>, greater<Edge>> minQueue;
// 建堆排序
for (size_t i = 0; i < n; i++)
{
for (size_t j = 0; j < n; j++)
{
if (i < j && _matrix[i][j] != MAX_W)
{
minQueue.push(Edge(i, j, _matrix[i][j]));
}
}
}
// 选出n-1条边
size_t size = 0;
W totalW = W();
UnionFindSet ufs(n);
while (!minQueue.empty())
{
Edge min = minQueue.top();
minQueue.pop();
// 判环 -> 并查集
if (!ufs.InSameSet(min._srci, min._dsti))
{
cout << _vertexs[min._srci] << "->" \
<< _vertexs[min._dsti] << ":" << min._w << endl;
minTree._AddEdge(min._srci, min._dsti, min._w);
ufs.Union(min._srci, min._dsti); // 入集
size++;
totalW += min._w;
}
else
{
cout << "Forming Ring: ";
cout << _vertexs[min._srci] << "->" \
<< _vertexs[min._dsti] << ":" << min._w << endl;
}
}
if (size == n - 1)
{
return totalW;
}
else
{
return W();
}
}

W Prim(Self& minTree, const W& src)
{
size_t srci = GetVertexIndex(src);
size_t n = _vertexs.size();
// 初始化minTree
minTree._vertexs = _vertexs;
minTree._indexMap = _indexMap;
minTree._matrix.resize(n);
for (size_t i = 0; i < n; i++)
{
minTree._matrix[i].resize(n, MAX_W);
}
// true & false表示该元素是否在该集合内
vector<bool> X(n, false);
vector<bool> Y(n, true);
X[srci] = true;
Y[srci] = false;
// 从X->Y集合中连接的边里面选出最小的边
priority_queue<Edge, vector<Edge>, greater<Edge>> minQueue;
// 先把srci连接的边添加到队列中
for (size_t i = 0; i < n; i++)
{
if (_matrix[srci][i] != MAX_W)
{
minQueue.push(Edge(srci, i, _matrix[srci][i]));
}
}
size_t size = 0;
W totalW = W();
while (!minQueue.empty())
{
Edge min = minQueue.top();
minQueue.pop();
// 最小边的目标也在X集合,则构成环
if (X[min._dsti])
{
cout << "Forming Ring:";
cout << _vertexs[min._srci] << "->" << _vertexs[min._dsti] << ":" << min._w << endl;
}
else
{
cout << _vertexs[min._srci] << "->" << _vertexs[min._dsti] << ":" << min._w << endl;
minTree._AddEdge(min._srci, min._dsti, min._w);
X[min._dsti] = true;
Y[min._dsti] = false;
size++;
totalW += min._w;
// 可能最小生成树已经生成,但是多了很多成环边,无须继续遍历
if (size == n - 1)
{
break;
}
// 将目标顶点连接的边加入到队列中
for (size_t i = 0; i < n; i++)
{
if (_matrix[min._dsti][i] != MAX_W && Y[i])
{
minQueue.push(Edge(min._dsti, i, _matrix[min._dsti][i]));
}
}
}
}
// 实际不一定存在最小生成树
if (size == n - 1)
{
return totalW;
}
else
{
return W();
}
}