赞
踩
**例如:**现在要找东西,假设有三个抽屉,东西在哪个抽屉不清楚,现在要将其找到,广度优先遍历的做法是:
思考:如何防止节点被重复遍历?
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(); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。