数据结构图及其遍历(邻接表存储方式的深度遍历和广度遍历)

建立无向图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;
}

猜你喜欢

转载自blog.csdn.net/m0_52910424/article/details/121468016