建立无向图G的邻接表存储结构,求其从任意顶点出发的广度优先搜索序列与深度优先搜索序列。(每个点优先去往周围未到达的点中编号最小的点)
输入格式:
第一行两个正整数n, m表示G中顶点数与边数
接下来m行每行两个正整数u,v表示u点与v点之间有一条无向边
若同一条边被输入两次,则自动增加一行输入
(1 <= u, v, w <= n)
(1 <= n <= 500, 1 <= m <= 2000)
最后一行一个正整数w表示遍历的起始顶点
输出格式
第一行n个正整数表示广度优先搜索序列
第二行n个正整数表示深度优先搜索序列
(若输入的起始顶点不存在,则不输出顶点搜索序列,输出“起始顶点不存在”)
样例输入
5 10
1 2
1 3
2 4
4 5
1 3
1 4
2 5
2 3
3 5
1 5
3 4
1
(其中1 3 重复输入)
样例输出
1 2 3 4 5
1 2 3 4 5
代码如下:
#include<iostream>
using namespace std;
#define VertexType int//顶点数据类型
#define Max_SIZE 501//头结点最大个数
int visited_1[Max_SIZE] = { 0 }; //用于存储节点是否被访问的标识
int visited_2[Max_SIZE] = { 0 }; //用于存储节点是否被访问的标识
int count_1 = 0, count_2 = 0;//用来区别是打印空格,还是换行
/*Graph的邻接表存储方式*/
int start,VerOrderNum = 0;//此时刻的顶节点个数
int iden=0;//用于判断是否输入了相同的数据
/*弧的结点结构(表结点)*/
typedef struct ArcNode {
int adjvex; // 该弧所指向的顶点(Vertue)的位置
struct ArcNode* nextarc; // 指向下一条弧的指针
} ArcNode,*P_ArcNode;
/*顶点的节点结构(头结点)*/
typedef struct VNode {
VertexType data; // 顶点信息
ArcNode* firstarc; // 指向第一条依附该顶点的弧
} VNode, AdjList[Max_SIZE];
/*图的定义*/
typedef struct
{
AdjList vertices; // 表头结点向量
int vexnum, arcnum; // 图的当前顶点数和弧数
} ALGraph;
void IniVertexdata(ALGraph& G); //初始化顶点数据,全设为-1
void creatVertexnode(ALGraph& G,int a,int b); //创建顶点,顶点存在不做处理,不存在创建
void Connection(ALGraph& G,int a,int b); //实现头结点和表结点的连接,以及表结点的创建扩展
void CreateGraph(ALGraph& G); //Graph的建立
void DestroyGraph(ALGraph& G); //图的销毁
void DFSTraverse(ALGraph G,int start); //深度优先搜索(纵向优先搜索)
void BFSTraverse(ALGraph G,int start); //广度优先搜索(横向优先搜索)
void IniVertexdata(ALGraph& G)
{
int i;
for (i = 0; i < Max_SIZE; i++)
{
G.vertices[i].data = -1;
G.vertices[i].firstarc = NULL;
}
}
void Connection(ALGraph& G,int a,int b)
{
int i;
P_ArcNode Temp, Temp_front = NULL; //临时变量
for (i = 0; G.vertices[i].data != -1; i++) {
if (G.vertices[i].data == a)
for (Temp = G.vertices[i].firstarc; Temp != NULL; Temp = Temp->nextarc)
if (Temp->adjvex == b)
{
iden = 1;//此时有相同的数据输入
return;
} //当表结点已经存在,退出函数
//否则建立表结点
}
for (i = 0; G.vertices[i].data != -1; i++)
{
if (G.vertices[i].data == a) {//找到头结点,在其后建立表结点
//根据ab关系创建表结点
P_ArcNode M_arcNode = new ArcNode;//分配内存空间
if (!M_arcNode)exit(-1);
M_arcNode->adjvex = b;
M_arcNode->nextarc = NULL;
//这边考虑如何连接
if (G.vertices[i].firstarc == NULL)G.vertices[i].firstarc = M_arcNode;
else {
if (G.vertices[i].firstarc->nextarc == NULL)G.vertices[i].firstarc->nextarc = M_arcNode;
for (Temp = G.vertices[i].firstarc; Temp != NULL; Temp_front = Temp, Temp = Temp->nextarc)//一直移动到表结点结尾
{
int judge = b > Temp->adjvex && (Temp->nextarc == NULL || (Temp->nextarc && b < Temp->nextarc->adjvex));//判断表示,决定节点的位置
if (judge){
P_ArcNode T_1 = Temp->nextarc;
Temp->nextarc = M_arcNode;
M_arcNode->nextarc = T_1;
}
}
}
break;
}
}
}
void creatVertexnode(ALGraph& G, int a, int b)
{
int i, A_inde = 0, B_inde = 0;//头节点是否存在标识
for (i = 0; G.vertices[i].data != -1; i++)
{ //存在头结点更改标识为1;
if (G.vertices[i].data == a)A_inde = 1;
if (G.vertices[i].data == b)B_inde = 1;
}
if (!A_inde) { //该顶点不存在需要建立
G.vertices[VerOrderNum].data = a;
VerOrderNum++;
}
if (!B_inde) {
G.vertices[VerOrderNum].data = b;
VerOrderNum++;
}
Connection(G, a, b);
Connection(G, b, a);
}
void CreateGraph(ALGraph& G)
{
int n, m, u, v, i; //n, m表示G中顶点数与边数,接下来m行每行两个正整数u,v表示u点与v点之间有一条无向边
cin >> n >> m;
G.vexnum = n; G.arcnum = m;
for (i = 0; i < m; i++)
{
cin >> u >> v;
creatVertexnode(G, u, v);
if (iden) { i--; iden = 0; }
}
cin >> start;
}
void DestroyGraph(ALGraph& G)
{
int i;
P_ArcNode temp_free,temp;
for (i = 0; i <G.vexnum; i++)
{
for (temp_free= G.vertices[i].firstarc,temp=temp_free->nextarc; temp != NULL;temp_free=temp, temp = temp->nextarc)
{
delete temp_free;
}
delete temp_free;
}
}
void DFSTraverse(ALGraph G, int v)
{
int iden = 0, w = 0, goal = -1;//goal是表示头结点的标识
if (v < 0)return;
for (int i = 0; G.vertices[i].data != -1; i++) {
if (G.vertices[i].data == v) {
iden = 1;
goal = i;
break;
}
}
cout << v;
count_1++;
if (count_1 != G.vexnum)cout << " ";
else cout << endl;
visited_1[v] = 1;
for (P_ArcNode it = G.vertices[goal].firstarc; it != NULL; it = it->nextarc)
{
if (visited_1[it->adjvex] == 0)
{
DFSTraverse(G, it->adjvex);
//return;
}
}
}
void BFSTraverse(ALGraph G,int v)
{
int queue[Max_SIZE], front=0, rear=0;//队列的简单表示
int iden = 0, goal = -1;//goal是表示头结点的标识
if (v < 0)return;
for (int i = 0; G.vertices[i].data != -1; i++) {
if (G.vertices[i].data == v) {
iden = 1;
goal = i;//记录头结点位置
break;
}
}
if (!iden) {
cout << "起始顶点不存在" << endl;
exit(-1);
}
else
{
int j;
P_ArcNode temp;
cout << v<<" ";
count_2++;
visited_2[v] = 1;//表示已经访问过
queue[rear++] = goal;//入队列
while (rear > front) {//队列不为空
j = queue[front++];//出列
temp = G.vertices[j].firstarc; //得到该头结点的下一个节点
while (temp != NULL) {
if (!visited_2[temp->adjvex]) { //若该节点没有被访问过
for (int i = 0; G.vertices[i].data != -1; i++) {
if (G.vertices[i].data == temp->adjvex) {
goal = i;//记录头结点位置
break;
}
}
queue[rear++] = goal;
//queue[rear++] = temp->adjvex;
visited_2[temp->adjvex] = 1;
cout << temp->adjvex; //打印
count_2++;
if (count_2 != G.vexnum)cout << " ";
else cout << endl;
}
temp = temp->nextarc;
}
}
}
}
int main()
{
ALGraph G;
IniVertexdata(G);
CreateGraph(G);
BFSTraverse(G, start);
DFSTraverse(G, start);
DestroyGraph(G);
return 0;
}