2021-1 查詢圖中單點路徑Paths的API 深搜/廣搜實現
阿新 • • 發佈:2021-01-22
給定一個起點和一幅圖,搜尋到目標點的路徑
方法
在搜尋過程中維護一個父親陣列,將當前節點記為他那些尚未標記的鄰接節點的父親,本質是一棵樹。列印路徑是從終點迭代找他的父親,可以用棧儲存,最後棧頂是起點,依次彈出就是路徑。這裡我採用了list的頭插法,效果一樣。
Path.h
#pragma once
#include<queue>
#include"Graph.h"
/********************如無必要,勿增實體**********************/
class Paths
{
public :
Paths(Graph& G, int s,bool isBfs=true);
bool hasPathto(int v);
list<int> pathTo(int v);
private:
vector<bool>* m_marked = nullptr;
vector<int>* m_father = nullptr;
int m_source = 0;
void dfs(Graph& G, int v);
void bfs(Graph& G, int v);
};
void testForPaths( );
Paths.cpp
#include "Paths.h"
Paths::Paths(Graph& G, int s,bool isBfs):m_source(s)
{
int n = G.V();
m_marked = new vector<bool>(n, false);
m_father = new vector<int>(n, -1);
isBfs ? bfs(G, s) : dfs(G, s);
}
bool Paths::hasPathto(int v)
{
return m_marked->at(v) ;
}
list<int> Paths::pathTo(int v)
{
list<int>* ans = new list<int>();
ans->push_front(v);//頭插法
while (m_father->at(v) != -1) {//未到起點
v = m_father->at(v);
ans->push_front(v);
}
return *ans;
}
inline
void Paths::dfs(Graph& G, int v)
{
m_marked->at(v) = true;
for (auto& next : G.adj(v)) {
if (!m_marked->at(next)) {
m_father->at(next) = v;//記錄自己的父親
dfs(G, next);
}
}
}
inline
void Paths::bfs(Graph& G, int v) {
m_marked->at(v) = true;
queue<int> Q;
Q.push(v);
while (!Q.empty()) {
int front = Q.front(); Q.pop();
for (auto& next : G.adj(front)) {
if (!(*m_marked)[next]) {
m_marked->at(next) = true;
m_father->at(next) = front;//記錄父親
Q.push(next);//相當於遞迴入棧
}
}
}
}
void testForPaths()
{
Graph G("data.txt");
int source = 0;
Paths path(G, source,true);
for (int i = 0; i < G.V(); ++i) {
printf_s("%2d to %2d : ", source, i);
if (path.hasPathto(i)) {
for (auto& v : path.pathTo(i)) {
if (source == v) printf_s("%2d", source);
else printf_s(" -%2d", v);
}
printf_s("\n");
}else
printf_s(" unconnected.\n");
}
}
data.txt
12
16
8 4
2 3
1 11
3 6
0 6
10 3
7 11
7 8
8 11
0 2
5 2
6 2
5 10
5 0
8 1
4 1
圖的標頭檔案在這裡:從檔案讀取構建圖https://blog.csdn.net/qq_34890856/article/details/112938237