//
// Created by Coder
//
#include <iostream>
#include <vector>
#include <stack>
#include <queue>
using namespace std;
class DirectedGraph{
private:
// 最大顶点数
const int V = 100000;
// vector实现的邻接表的定义
// 不考虑边权,存储类型为int型
vector<int> e[V];
int visit[V];
// 邻接表的初始化操作
// 将起点为`i`的边链表全部清空
void init() {
for (int i=0; i<V; i++) {
e[i].clear();
visit[i] = -1;
}
}
public:
bool Visited(int v) {
return visit[v] != -1;
}
void Visit(int v) {
visit[v] = 1;
cout<<v<<endl;
}
// 增加边
// 新增顶点`i`到顶点`j`的边
void AddEdge(int i, int j) {
e[i].push_back(j);
}
// 查询边
bool SearchEdge( int j, int k) {
for (int i=0; i<V; i++) {
//e[i][0] ----- 查询以`i`为起点的第一条边`i->e[i][0]`
for (int j=0; j<(int)e[i].size(); ++j) {
if (e[i][j] == k) { // 查询边`i->k`
return true;
}
}
}
return false;
}
int GetFirstNotVisit(int v) {
for (int j=0; j<e[v].size(); j++) {
if(!Visited(e[v][j]))
return j;
}
return -1;
}
//从v开始深度优先遍历
void DFS(int v) {
Visit(v);
stack<int> s;
s.push(v);
while (!s.empty()) {
//找到下一个待访问的邻接点
int next = GetFirstNotVisit(s.top());
if (next != -1) { //还能继续深搜(未达到最大深度),继续
//找到栈顶元素第一个未被访问的临接点(也就是更深的邻接点),访问之
Visit(GetFirstNotVisit(s.top()));
//入栈
s.push(GetFirstNotVisit(s.top()));
} else { //不能继续深搜下去,回溯
//出栈(回溯)到能找到有邻接点未被访问的节点
s.pop();
}
}
}
//整个图的深搜
void DFSTraverse() {
for (int i=0; i<V; i++) {
if (!Visited(i)) {
BFS(i);
}
}
}
//单节点广搜
void BFS(int v) {
//访问当前节点
Visit(v);
queue<int> s;
s.push(v);
while (!s.empty()) {
//取队首元素
int front = s.front();
//出队
s.pop();
//对于队首元素,访问其所有未访问的邻接点
//将未访问的邻接点入栈
for (int i=0; i<e[front].size(); i++) {
if (!Visited(e[front][i])) {
Visit(e[front][i]);
s.push(e[front][i]);
}
}
}
}
//整个图的广搜
void BFSTraverse() {
for (int i=0; i<V; i++) {
if (!Visited(i)) {
BFS(i);
}
}
}
};
更新
加入泛型支持,节点类型要重载=和==运算符,代码有点粗糙,c++水平还是渣。根据严蔚敏的数据结构书中对广搜和深搜的定义书写,代码经过测试。
//
// Created by Coder on 2018/2/13.
//
#include <iostream>
#include <vector>
#include <stack>
#include <queue>
using namespace std;
template <class Type, class Weight>
class DirectedGraph{
private:
//最大顶点数
const static int V = 10000;
//当前的顶点数
int VertexCount = 0;
//存储所有的顶点
vector<Type> vertexs;
// vector实现的邻接表的定义
// 注意edge[i]中的每一个元素都表示节点vertex数组中的下标
// edge[i][j]表示 vertex[i]与vertex[edge[i][j]]有通路
vector<int> edge[V];
//weight和数组edge一一对应
//weight[i][j]表示 vertex[i]与vertex[edge[i][j]]通路的权
vector<Weight> weight[V];
int visit[V];
public:
DirectedGraph() {
// 邻接表的初始化操作
// 将起点为`i`的边链表全部清空
for (int i=0; i<V; i++) {
edge[i].clear();
visit[i] = -1;
}
}
bool SearchVertex(Type v) {
for (int i=0; i<vertexs.size(); i++) {
if (vertexs[i] == v) {
return true;
}
}
return false;
}
bool InsertVertex(Type v) {
if(!SearchVertex(v)) {
vertexs.push_back(v);
VertexCount++;
return true;
}
return false;
}
int FindIndex(Type v) {
for (int i=0; i<vertexs.size(); i++) {
if (vertexs[i] == v) {
return i;
}
}
return -1;
}
bool InsertEdge(Type from, Type to, Weight w) {
int i = FindIndex(from);
int j = FindIndex(to);
if(i != -1 && j != -1) {
//添加边
edge[i].push_back(j);
//添加权
weight[i].push_back(w);
}
}
bool Visited(int index) {
return visit[index] != -1;
}
//访问vertexs[index]
void Visit(int index) {
visit[index] = 1;
cout<<vertexs[index]<<endl;
}
// 查询边
bool SearchEdge( Type from, Type to) {
int i = FindIndex(from);
int j = FindIndex(to);
if (i != -1) {
for (int k=0; k<(int)edge[i].size(); ++k) {
if (edge[i][k] == j) { // 查询边`i->j`
return true;
}
}
}
return false;
}
//打印顶点
void PrintVertex() {
for (int i=0; i<vertexs.size(); i++) {
cout<<vertexs[i]<<endl;
}
}
//打印边
void PrintEdge() {
for (int i=0; i<VertexCount; i++) {
for (int j=0; j<edge[i].size(); j++) {
cout<<vertexs[i]<<"->"<<vertexs[edge[i][j]]<<" weight:"<<weight[i][j]<<endl;
}
}
}
//返回v第一个没被访问的邻接点下标
//index是v在vertexs中的下标
int GetFirstNotVisit(int index) {
if (index != -1) {
//遍历v的邻接点
for (int j=0; j<edge[index].size(); j++) {
if(!Visited(edge[index][j]))
return edge[index][j];
}
}
return -1;
}
//从v开始深度优先遍历
void DFS(int index) {
//访问该节点
Visit(index);
//存储节点的下标
stack<int> s;
s.push(index);
while (!s.empty()) {
//找到下一个待访问的邻接点下标
int next = GetFirstNotVisit(s.top());
if (next != -1) { //还能继续深搜(未达到最大深度),继续
//找到栈顶元素第一个未被访问的临接点(也就是更深的邻接点),访问之
Visit(next);
//入栈
s.push(next);
} else { //不能继续深搜下去,回溯
//出栈(回溯)到能找到有邻接点未被访问的节点
s.pop();
}
}
}
//整个图的深搜
void DFSTraverse() {
for (int i=0; i<VertexCount; i++) {
if (!Visited(i)) {
DFS(i);
}
}
}
//单节点广搜
void BFS(int index) {
//访问当前节点
Visit(index);
queue<int> s;
s.push(index);
while (!s.empty()) {
//取队首元素
int front = s.front();
//出队
s.pop();
//对于队首元素,访问其所有未访问的邻接点
//将未访问的邻接点入栈
for (int i=0; i<edge[front].size(); i++) {
if (!Visited(edge[front][i])) {
Visit(edge[front][i]);
s.push(edge[front][i]);
}
}
}
}
//整个图的广搜
void BFSTraverse() {
for (int i=0; i<VertexCount; i++) {
if (!Visited(i)) {
BFS(i);
}
}
}
};
int main() {
DirectedGraph<char, int> graph;
int total, weight;
char from, to;
cin>>total;
for (int i=0; i<total; i++) {
cin>>from>>to;
graph.InsertVertex(from);
graph.InsertVertex(to);
graph.InsertEdge(from, to, weight);
graph.InsertEdge(to, from, weight);
}
// graph.PrintVertex();
// graph.PrintEdge();
// graph.DFSTraverse();
graph.BFSTraverse();
}