フォーチュンの基礎はclass6-被写体2第一のトラバース幅と深さ優先トラバーサルを残し
1.タイトル:幅優先と深さ優先探索トラバーサル
2.幅優先トラバーサル
(1)分析
応じて、ヘッドノードから幅優先トラバーサル開始を意味近い出力ノードに現在のステップ数と原則、全てのノードがトラバース
7,5は、続いて、1から始まる場合2,3,4-最も近い最初のトラバースから、 6。同じバッチ出力順序内部2,3,4または7,5,6は必要とされません。ノード3は、依然として回避繰り返しにノード7 3トラバーサル順序を指して横断した後、構造体は、使用unordered_setが横断か否かが判断されます。
次のように具体的なプロセスである。
①キューを使用して実装;
②幅にソースノードから順にキューに、ポップアップを、
③、キュー内のキューにされていない全ての隣接ノードへのノードの各点をポップし、
④キューが空になるまで。
(2)コアコード
void bfs(Node* nodes)
{
if(nodes == NULL) return ; //空节点直接返回
queue<Node*> q;
unordered_set<Node*> set; //用于判断是否遍历过
q.push(nodes);
set.insert(nodes);
while(!q.empty())
{
Node* help = q.front();
cout<<help->value<<" ";
q.pop();
//把队头指向的所有未遍历节点加入队列和set
for(Node* t: help->nexts)
{
if(set.find(t) == set.end()) //未在set中
{
q.push(t);
set.insert(t);
}
}
}
}
前記深さ優先トラバーサル
(1)分析
深さ優先探索は、互いに続く長い終了する方法です。
次のように具体的なプロセスである:
①スタック実装の使用を、
②ソースノードからノードによるスタックへの深さが始まり、次にポップアップ;
③ノードは隣接点を積層するれていない場合、各ポイントをポップに、ノードの存在しませんスタックスタックに置か隣人; ④スタックが空になるまで。
図上記各ステップスタック容器とセットについて次のように
スタック:. 1
組:. 1
スタック:空
集合:. 1
スタック:1,2
セット:1,2
スタック:1,2,7
セット:1,2,7
スタック:1,2,7,3、
SET:1,2,7,3
スタック:1,2,7,3,5
SET:1,2,7,3,5
スタック:1,2,7,3
セット:1,2,7,3,5
スタック:1,2,7
セット:1,2,7,3,5
スタック:1,2
セット:1,2,7,3,5
スタック:. 1
SET: 1,2,7,3,5
スタック:1、4
SET:1,2,7,3,5,4
スタック:1,4,6-
SET:1,2,7,3,5,4,6
スタック:1、4
セット:1,2,7,3,5,4,6
スタック:1、
SETスタック:空の
セット:1,2,7,3,5,4,6
(2)コアコード
void dfs(Node* node)
{
if(node == NULL) return;
stack<Node*> s;
unordered_set<Node*> set;
s.push(node);
set.insert(node);
cout<<node->value<<" "; //第一个元素直接输出
while(!s.empty())
{
Node* help = s.top();
s.pop();
for(auto tmp : help->nexts)
{
if(set.find(tmp) == set.end()) //未遍历
{
s.push(help);
s.push(tmp);
set.insert(tmp);
cout<<tmp->value<< " ";
break; //一次只找一个
}
}
}
}
4.完全なコード
#include <iostream>
#include<unordered_map>
#include<unordered_set>
#include<list>
#include<vector>
#include<queue>
#include<stack>
#include"Node.h"
#include"Edge.h"
#include"Graph.h"
#include"GraphGenerator.h"
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
void dfs(Node* node)
{
if(node == NULL) return;
stack<Node*> s;
unordered_set<Node*> set;
s.push(node);
set.insert(node);
cout<<node->value<<" "; //第一个元素直接输出
while(!s.empty())
{
Node* help = s.top();
s.pop();
for(auto tmp : help->nexts)
{
if(set.find(tmp) == set.end()) //未遍历
{
s.push(help);
s.push(tmp);
set.insert(tmp);
cout<<tmp->value<< " ";
break; //一次只找一个
}
}
}
}
void bfs(Node* node)
{
if(node == NULL) return ; //空节点直接返回
queue<Node*> q;
unordered_set<Node*> set; //用于判断是否遍历过
q.push(node);
set.insert(node);
while(!q.empty())
{
Node* help = q.front();
cout<<help->value<<" ";
q.pop();
//把队头指向的所有未遍历节点加入队列和set
for(Node* t: help->nexts)
{
if(set.find(t) == set.end()) //未在set中
{
q.push(t);
set.insert(t);
}
}
}
}
int main(int argc, char** argv) {
GraphGenerator g;
vector<vector<int> > matrix= {{12,1,2},
{13,1,3},
{14,1,4},
{9,2,7},
{10,7,3},
{8,3,5},
{10,4,6}};
Graph graph = g.createGraph(matrix);
//test :某节点所指向的节点
cout<<"1所指向:";
Node* testnode = graph.nodes[1];
for(auto n : testnode->nexts)
cout<< n->value<<"、";
//test :输出所有节点与边
cout<<endl<<"-----------------------------------------------"<<endl ;
cout<<"所有节点为: "<<endl ;
unordered_map<int,Node*>::iterator ite1 = graph.nodes.begin();
while(ite1 != graph.nodes.end())
{
cout << "节点: "<<(ite1)->second->value<<"、";
//cout << "节点: "<<(ite1)->first<<"、";
ite1++;
}
cout<<endl<<"-----------------------------------------------"<<endl ;
cout<<"节点与边为: "<<endl ;
unordered_set<Edge*>::iterator ite = graph.edges.begin();
while(ite != graph.edges.end())
{
cout << "边权为 "<<(*ite)->weight<<" ";
cout<<(*ite)->from->value <<"---->"<<(*ite)->to->value<<endl;
ite++;
}
Node *node = graph.nodes[1];
cout<<endl<<"-----------------------------------------------"<<endl ;
cout<<"宽度优先遍历bfs: "<<endl;
bfs(node);
cout<<endl<<"-----------------------------------------------"<<endl ;
cout<<"深度优先遍历dfs: "<<endl;
dfs(node);
return 0;
}
注:Graph.hのヘッダなどのメモリマップと表現しました。