图——广度优先遍历和深度优先遍历——邻接表表示法
// ConsoleApplication2.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "stdafx.h"
#include<iostream>
#include<vector>
#include<algorithm>
#include<numeric>
#include<list>
#include<iterator>
#include<deque>
#include<stack>
#include<algorithm>
#include<forward_list>
using namespace std;
struct Edge //边的定义
{
Edge(int i):node(i),nextEdge(NULL){ }
int node;
Edge *nextEdge;
};
struct Node //节点的定义
{
Node(int i):value(i),firstEdge(NULL){}
int value;
Edge *firstEdge;
};
struct Figure
{
vector<Node*> nodes;//存储节点
int nodeNums, edgeNums;
};
class Solution {
public:
//构建表
void createFigure(Figure &figure)
{
//首先输入边的信息
cout << "请输入节点的数目:" ;
cin >> figure.nodeNums;
cout << "请输入边的数目:";
cin >> figure.edgeNums;
for (int i = 0; i < figure.nodeNums; ++i) //输入节点信息
{
figure.nodes.push_back(new Node(i));
}
for (int i = 0; i < figure.nodeNums; ++i)//输入边的信息
{
cout << "请输入相关的边:";
int node1, node2;
cin >> node1 >> node2;
auto it = figure.nodes.begin();
while (it!=figure.nodes.end() && node1!=(*it)->value)
{
it++;//找到节点
}
if (it != figure.nodes.end())
{
//第一种插入方式
/*Edge* temp = (*it)->firstEdge;
(*it)->firstEdge = new Edge(node2);
(*it)->firstEdge->nextEdge = temp;*/
//第二种插入方式:
if ((*it)->firstEdge == NULL)
{
(*it)->firstEdge = new Edge(node2);
}
else
{
Edge* edge = (*it)->firstEdge;
while (edge->nextEdge != NULL)
{
edge = edge->nextEdge;
}
edge->nextEdge = new Edge(node2);
}
}
}
}
void CreateAFigure(Figure &figure)
{
figure.nodeNums = 6;
for (int i = 0; i < figure.nodeNums; ++i) //输入节点信息
{
figure.nodes.push_back(new Node(i));
}
figure.nodes[0]->firstEdge = new Edge(1);
figure.nodes[0]->firstEdge->nextEdge = new Edge(2);
figure.nodes[1]->firstEdge = new Edge(3);
figure.nodes[1]->firstEdge->nextEdge = new Edge(4);
figure.nodes[2]->firstEdge = new Edge(3);
figure.nodes[4]->firstEdge = new Edge(5);
}
void printFigure(Figure figure)//打印图
{
cout << "打印图的结构:" << endl;
for (int i = 0; i < figure.nodeNums; i++)
{
cout <<"v_"<< figure.nodes[i]->value << ": ";
if (figure.nodes[i]->firstEdge != NULL)
{
// cout << figure.nodes[i]->firstEdge->node << " ";
Edge* edge = figure.nodes[i]->firstEdge;
while (edge!=NULL)
{
cout << "v_"<<edge->node << " ";
edge = edge->nextEdge;
}
}
cout << endl;
}
}
//深度优先遍历
void DFSTraver(Figure figure)
{
setVisit(figure);
for (int i = 0; i < figure.nodeNums; ++i)
{
if (visisted[i] == false)//第i个节点没有被访问
DFS(figure.nodes[i], figure);
}
}
void DFS(Node* node,Figure figure)
{
if (visisted[node->value] == false)//如果该节点没有被访问过
{
cout << "v_" << node->value << " ";
visisted[node->value] = true;
}
if (node->firstEdge == NULL) return;
if(visisted[node->firstEdge->node]==false)//第一个边没有被访问,访问第一条边
DFS(figure.nodes[node->firstEdge->node],figure);
if (visisted[node->firstEdge->node] == true)//第一个边已经被访问过了,访问第二条没有被访问的边
{
//首先找到第一条没有被访问的边
Edge* edge = node->firstEdge->nextEdge; //第一条可访问的边
while (edge!=NULL)
{
if (visisted[edge->node] == true)//对应的节点已经访问过了
edge = edge->nextEdge;
else
break;//对应的节点没有被访问过
}
if (edge == NULL) //初始节点对应的边都访问完了
return;
else
DFS(figure.nodes[edge->node], figure);//访问第一条没有访问的边
}
}
//广度优先遍历
void BFSTravers(Figure figure)
{
setVisit(figure);
for (int i = 0; i < figure.nodeNums; ++i)
{
if (visisted[i] == false)
{
BFS(figure.nodes[i], figure);
}
}
}
deque<Node*> parent;
deque<Node*> child;
//此处应该设置两个队列;一个父队列,一个子队列,父亲队列用来存储将要答应的节点,子队列用来存储将要打印的节点
void BFS(Node* node,Figure figure)
{
//if (visisted[node->value] == false)//如果该节点没有被访问过
//{
// cout << "v_" << node->value << " "; //打印跟节点
// visisted[node->value] = true;
//}
//if (node->firstEdge == NULL) return;
//else
//{
// cout << "v_" << node->firstEdge->node << " "; //把接下来的根节点存入队列Node中
// visisted[node->firstEdge->node] = true;
// parent.push(figure.nodes[node->firstEdge->node]);
//}
//Edge* edge = node->firstEdge->nextEdge;
//while (edge!=NULL)
//{
// cout << "v_" << edge->node << " ";
// visisted[node->firstEdge->node] = true;
// parent.push(figure.nodes[edge->node]);
// edge = edge->nextEdge;
//}
child.push_back(node);
while (!child.empty())
{
parent = child;
child.clear();
while (!parent.empty())
{
if (visisted[parent.front()->value] == false)
{
cout << "v_" << parent.front()->value << " "; //打印跟节点
visisted[parent.front()->value] = true;
}
Edge* edge = parent.front()->firstEdge;
while (edge!=NULL)
{
child.push_back(figure.nodes[edge->node]);
edge = edge->nextEdge;
}
parent.pop_front();
}
}
}
vector<bool> visisted;//访问过的设置为ture,没访问过设置为false
void setVisit(Figure figure)
{
visisted.clear();
for (int i = 0; i < figure.nodeNums; i++)
{
visisted.push_back(false);
}
}
};
int main()
{
Solution so;
Figure figure;
so.CreateAFigure(figure);
cout << "节点结构:" << endl;;
so.printFigure(figure);
cout << "深度优先遍历:";
so.DFSTraver(figure);
cout << endl;
cout << "广度优先遍历:";
so.BFSTravers(figure);
cout << endl;
return 0;
}