BFS和DFS深度优先遍历和广度优先遍历

 

紧接着上一个博客,补上了广度优先遍历

//数据结构之图的存储结构,初始化,遍历,应用

#include<iostream>
#include <stdlib.h>
#include<string>
#include<stdio.h>

using namespace std;

#define VertexType char//顶点类型
//存储结构
#define MaxSize 100//顶点数目最大值
typedef struct ArcNode {//边表结点存储结构
	int adjvex;//adj是邻接的意思,该弧所指向的顶点的位置,即顶点数组的位置
	 ArcNode *next;//指向下一个边的指针
}ArcNode;
typedef struct VNode {//顶点表结点及邻接表存储结构
	VertexType data;//定点类型
	ArcNode *firstedge;//第一个边结点的指针

}Vnode,AdjList[MaxSize];//AdjList即邻接表
typedef struct {//图的存储结构
	AdjList adjlist1;//一个图对应着一个邻接表存储
	int vexnum, arcnum;//图的结点个数和边的个数,在遍历和应用的时候会用到

}Graph;
#define quedata int
typedef struct quenode
{
	quedata data;
	quenode* next;
}quenode;
typedef struct queque
{
	quenode* head;

	quenode* tail;

}queue;
void _init(queue &Q)
{
	//Q.head = NULL;
	Q.head = (quenode*)malloc(sizeof(quenode));
	Q.tail = Q.head;
}
bool _empty(queue Q)
{
	if (Q.head == Q.tail)return true;
	else
		return false;
}

void qpush(queue &Q, quedata e)
{
	quenode* s;
	s = (quenode*)malloc(sizeof(quenode));
	s->data = e;
	s->next = NULL;
	Q.tail->next = s;
	Q.tail = s;

}
bool qpop(queue &Q, quedata &v)
{
	if (Q.head == Q.tail)return false;

	quenode* s;
	s = (quenode*)malloc(sizeof(quenode));
	s = Q.head->next;
	 v= s->data;
	Q.head->next = s->next;
	if (Q.tail == s)Q.tail = Q.head;
	free(s);

	
}

//初始化
void graph_init(Graph &g)//这里用一个实例图
    //          A
	//        / | \
    //       /  |  \
	//      /   |   \
	//     B    D----C-----G
	//     |         |
	//     E         F
	//
{

	g.arcnum = 7;
	g.vexnum = 7;
	g.adjlist1[0].data = 'A';
	g.adjlist1[1].data = 'B';
	g.adjlist1[2].data = 'C';
	g.adjlist1[3].data = 'D';
	g.adjlist1[4].data = 'E';
	g.adjlist1[5].data = 'F';
	g.adjlist1[6].data = 'G';
	ArcNode *p;
	{//这个初始化看着麻烦但是代码都是可以重用的,而且应该能改成循环手动输入
	
		p = (ArcNode*)malloc(sizeof(ArcNode)); p->next = NULL;
		p->adjvex = 1;
		g.adjlist1[0].firstedge = p;
	
		p = (ArcNode*)malloc(sizeof(ArcNode)); p->next = NULL;
		p->adjvex = 2;
		g.adjlist1[0].firstedge->next = p;


		p = (ArcNode*)malloc(sizeof(ArcNode)); p->next = NULL;
		p->adjvex = 3;
		g.adjlist1[0].firstedge->next->next = p;
		//p->next = NULL;
		//adjlist1[0],下面以此类推.代码重用,改一些数值即可
		//A
		
	}
	{
		//B
		p = (ArcNode*)malloc(sizeof(ArcNode)); p->next = NULL;
		p->adjvex = 0;
		g.adjlist1[1].firstedge = p;

		p = (ArcNode*)malloc(sizeof(ArcNode)); p->next = NULL;
		p->adjvex = 4;
		g.adjlist1[1].firstedge->next = p;
		
	}
	{
		//C
		p = (ArcNode*)malloc(sizeof(ArcNode)); p->next = NULL;
		p->adjvex = 0;
		g.adjlist1[2].firstedge = p;

		p = (ArcNode*)malloc(sizeof(ArcNode)); p->next = NULL;
		p->adjvex = 3;
		g.adjlist1[2].firstedge->next = p;

		p = (ArcNode*)malloc(sizeof(ArcNode)); p->next = NULL;
		p->adjvex = 5;
		g.adjlist1[2].firstedge->next->next = p;

		p = (ArcNode*)malloc(sizeof(ArcNode)); p->next = NULL;
		p->adjvex = 6;
		g.adjlist1[2].firstedge->next->next->next = p;
		
	}
	{
		//D
		p = (ArcNode*)malloc(sizeof(ArcNode)); p->next = NULL;
		p->adjvex = 0;
		g.adjlist1[3].firstedge = p;

		p = (ArcNode*)malloc(sizeof(ArcNode)); p->next = NULL;
		p->adjvex = 2;
		g.adjlist1[3].firstedge->next = p;
		
	}
	{//E
		p = (ArcNode*)malloc(sizeof(ArcNode)); p->next = NULL;
		p->adjvex = 1;
		g.adjlist1[4].firstedge = p;

		
		
	}
	{//F
		p = (ArcNode*)malloc(sizeof(ArcNode)); p->next = NULL;
		p->adjvex = 2;
		g.adjlist1[5].firstedge = p;


		
	}
	{//G
		p = (ArcNode*)malloc(sizeof(ArcNode)); p->next = NULL;
		p->adjvex = 2;
		g.adjlist1[6].firstedge = p;


		
	}

	
}
void visit(int v,Graph g)
{
	cout << g.adjlist1[v].data;
}
//BFS,即广度优先遍历

bool visited[MaxSize];
void initvisit(Graph g)//图g的判定数组初始化false
{
	for (int i = 0; i < g.vexnum; i++)
	{
		visited[i] = false;
	}
}
void BFS(Graph g, int v)
{
	queue Q;//定义一个工作队列
	ArcNode *p;//工作指针
	_init(Q);//队列初始化
	visit(v,g);//访问v下标的结点
	visited[v] = true;//访问后置正
	qpush(Q, v);//访问后入队列
	while (!_empty(Q))
	{
		qpop(Q,v);//弹出队首,记录队首结点的下标数
		p = g.adjlist1[v].firstedge;//该下标数对应的边表开始循环访问
		while (p)
		{
			if (!visited[p->adjvex])//该节点没访问过的话就访问,然后入队列
			{//访问过了的话就下一个
				visit(p->adjvex,g);
				visited[p->adjvex] = true;
				qpush(Q, p->adjvex);
			}
			p = p->next;
			//直到这个下标对应节点的边表访问结束后
		}
		//继续弹出队首这样循环往复直到所有遍历完成
	}
}
//DFS,即深度优先遍历
void DFS(Graph g, int v)
{
	
	ArcNode *p;//工作指针
	visit(v,g);//访问该点结点
	visited[v] = true;//判定数组置为正
	p = g.adjlist1[v].firstedge;//该点结点的头指针赋值给工作指针
	while (p != NULL) {
		if (!visited[p->adjvex]) {//访问了就下一个,没访问就以这个点继续递归
			DFS(g, p->adjvex);
		}
		p = p->next;
	}
}
int main()
{

	Graph g;
	graph_init(g);
	initvisit(g);
	//          A
	//        / | \
    //       /  |  \
	//      /   |   \
    //     B    D----C-----G
//         |         |
//         E         F
//
	string A1 = "          A";	
	string A2 = "        / | \\";
	string A3 = "       /  |  \\";
	string A4 = "      /   |   \\";
	string A5 = "     B    D----C-----G";
	string A6 = "     |         |";
	string A7 = "     E         F";
	cout << "初始化图为:" << endl;
	cout << A1 << endl;
	cout << A2 << endl;
	cout << A3 << endl;
	cout << A4 << endl;
	cout << A5 << endl;
	cout << A6 << endl;
	cout << A7 << endl;
	cout << "注意ABCDEFG分别对应下标0123456\n" << endl;
	cout << "邻接表为:" << endl;
	for (int i = 0; i < g.vexnum; i++)
	{
		cout << g.adjlist1[i].data << "|firstedge->";
		ArcNode *p;
		p = g.adjlist1[i].firstedge;
		while (p != NULL)
		{
			cout << p->adjvex << "|next->";
			p = p->next;
		}
		cout << "NULL\n";
	}
	cout << "深度遍历输出为:" << endl;
	DFS(g, 0);
	cout << endl;

	initvisit(g);
	cout << "广度遍历输出为:" << endl;
	BFS(g, 0);
	cout << endl;
	
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值