广度优先搜索介绍及其算法的实现(C++)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wjb123sw99/article/details/81676624

本章将讲述一种图算法------广度优先算法;

该算法的应用领域有:

1、编写国际跳棋AI,计算最少走多少步能获胜;

2、编写拼写检查器,计算最少编辑多少个地方就可将拼错的单词改成正确的单词;

3、根据人际关系,找到最近的医生等。

有人会问“图”是什么?

图由节点和边组成,一个节点可能有众多相邻的节点相连,这些节点成为邻居。

而广度优先算法解决的就是二个节点间最短路径问题及是否能抵达另一点的问题。

其算法主要意思是,如果要查找AB二节点间的最短距离,则先遍历A的相连节点,这些节点称为一度关系,当一度关系里没有时,则遍历一度关系的相邻节点,这些节点称为二度关系,直到遍历到B点,则该遍历路径为最短节点。

让我们看下具体的例子和代码实现。

问题:找到下图中起点到郑州所经历最少城市的路径 

根据广度遍历搜索的思想,其搜索步骤为:

1、先遍历起点相邻的节点:上海、南京、福州

2、再遍历二度关系上海、南京、福州的相邻节点:广州、南昌、济南

3、再遍历三度关系广州、南昌、济南的相邻节点:武汉、郑州、石家庄

4、找到起点到郑州最短路径

以下是根据广度遍历算法实现的C++程序:

#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <iostream>
#include "stdarg.h"
#include <queue>

using namespace std;
class city;

class city {
public:
	city(const int n, const string cityname);
	~city();
	int init(int cnt, ...);  //初始化相连城市数
	void outname();
	int judge(string end, city *master, city *start);   //判断是否抵达终点
	int findcity(string name, city *start);  //寻找相邻城市
	int findcity_rank(string name);  //寻找城市
//private:
	city *last; //上一个城市
	int bit;  //防止重复查找
	int num; //相连城市数
	city **city_array; //相连城市数组
	string myname;  //城市名字
};

city::city(const int n, const string cityname)
{
	last = 0;
	num = n;
	bit = 0;
	city_array = (city**)malloc(n * sizeof(city *));
	myname = cityname;
}

city::~city()
{
	free(city_array);
}

int city::init(int cnt, ...)
{
	if (cnt != num)
	{
		cout << cnt << ";" << num << endl;
		cout << "init error:" <<myname<<endl;
		return -1;
	}
	int sum = 0;
	int i=0;
	va_list ap;
	va_start(ap, cnt);
	for (i = 0; i < cnt; ++i)
		city_array[i] = va_arg(ap, city*);
	va_end(ap);
	return 0;
}

void city::outname()
{
	cout << myname << endl;
}

int city::judge(string end, city *master, city *start)   //判断是否抵达终点,抵达终点则输出路径
{
	city *roadpath=this;
	if (last != 0)
	{
		return -1;
	}

	last = master;
	if (end != myname)
		return -2;
	while (roadpath != start )
	{
		roadpath->outname();
		roadpath = roadpath->last;
	}
	roadpath->outname();
	return 0;
}

int city::findcity(string name, city *start)  //遍历相邻城市
{
	int ret=1;
	int i,j;
	if (bit != 0)
	{
		return  -3;
	}
	bit = 1;  //代表已经遍历过该城市
	j = 0;
	while(j<num)
	{
		ret = city_array[j]->judge(name, this, start);
		if (ret == 0)
		{
			return 0;
		}
		j++;
	}
	return -1;
}

int city::findcity_rank(string name) //寻找城市, 输入要寻找的名字和遍历的级别
{
	int i = 0, j = 0,ret=0;
	city *node = 0;
	queue <city *> myQ;

	myQ.push(this);
	/* 开始从一度关系遍历 */
	while (!myQ.empty())
	{
		node = myQ.front();
		myQ.pop();
		ret=node->findcity(name, this);
		if (ret == 0)
		{
			return 0;//找到
		}
		else if (ret != -3)
		{
			for (int i = 0; i < node->num; i++)
			{
				myQ.push(node->city_array[i]);  //没找到,把下一度关系添加到队列中
			}
		}
	}   

	cout << "not find city road:" << this->myname << "-----" << name << endl;
	return -1;
}

int main()
{
	/* 初始化地图 */
	city origin(3, "origin"), shanghai(1, "shanghai"), nanjin(2, "nanjin"), 
		 fuzhou(3, "fuzhou"), guangzhou(1,"guangzhou"), nanchang(2, "nanchang"), 
		 wuhan(2, "wuhan"), zhenzhou(2, "zhenzhou"), jinan(3, "jinan"),shijiazhuang(1, "shijiazhuang");
	origin.init(3, &shanghai, &nanjin, &fuzhou);
	shanghai.init(1, &origin);
	nanjin.init(2, &origin, &jinan);
	fuzhou.init(3, &origin, &guangzhou, &nanchang);
	guangzhou.init(1, &fuzhou);
	nanchang.init(2, &fuzhou, &wuhan);
	wuhan.init(2, &nanchang, &zhenzhou);
	zhenzhou.init(2, &wuhan, &jinan);
	jinan.init(3, &nanjin, &zhenzhou, &shijiazhuang);
	shijiazhuang.init(1, &jinan);

	/* 寻找路经 */
	origin.findcity_rank("zhenzhou");
	return 0;
}

欢迎技术交流+Q:869538952

猜你喜欢

转载自blog.csdn.net/wjb123sw99/article/details/81676624
今日推荐