北京市朝阳区社会保障住房建设网站网站优化策划书
目录
1、图的遍历
2、深度优先搜索算法
3、广度优先搜索算法
谢谢帅气美丽且优秀的你看完我的文章还要点赞、收藏加关注
没错,说的就是你,不用再怀疑!!!
希望我的文章内容能对你有帮助,一起努力吧!!!
1、图的遍历
图的遍历是对树的遍历的推广,是按照一种规划(或者说是一种次序)访问图中各顶点一次,并且只能 访问一次,亦或者是将网状结构按照某种规划进行线性化。
对于图的遍历通常有两种方式:
- 广度优先搜索算法(Breath First search)BFS
- 深度优先搜索算法(Depth First search)DFS
两者是现代人工智能AI的基础。
2、深度优先搜索算法
深度优先搜索算法(Depth First search)DFS
设初始化的时候,图中各个顶点均为被访问过。从图中某个顶点(V0)出发,访问V0,然后搜索V0的 邻接顶点Vi,再以Vi为基础访问Vi的邻接顶点(依次下去...)(深度优先)。若某个顶点没有邻接顶点 (邻接顶点均被访问完毕),则回溯到它上一个顶点,然后再从它的上一个顶点开始继续进行邻接顶点 的访问,直到所有的顶点都被访问完毕。
***DFS示例代码***
#include <iostream>
#include <cstring>// 关系类型
typedef struct relation
{int index; // 下标int weight; // 权值struct relation *next; // 下一个关系的顶点的下标指针
}Relation_t;// 顶点类型
typedef struct
{std::string data; // 顶点数据Relation_t *first; // 该顶点的关系集
}Vertex_t;// 当前顶点数
int current_count = 0;/*@brief 创建一个图:邻接表@param count 该图的最大顶点数量 @return 成功返回创建好的图指针
*/
Vertex_t *creatGraph(int count)
{// 申请空间Vertex_t *graph = new Vertex_t[count];// 初始化memset(graph,0,sizeof(Vertex_t)*count);std::cout << "请输入顶点数据空格分开(“结束”输入):";// 接受顶点while(1){std::string data = "结束";std::cin >> data;if(data == "结束")break;if(current_count == count)break;// 新增顶点位置graph[current_count].data = data;graph[current_count].first = nullptr;current_count++;}// 增加关系while(1){std::cout << "请输入顶点关系(结束 结束 -1):";// 出发顶点和终止顶点 权值std::string start;std::string end;int data;std::cin >> start >> end >> data;if(start=="结束"||end=="结束"||data == -1)break;// 存储关系// 获取start和end在图数组的什么位置int index_s = 0,index_e = 0;for(;index_s < current_count;index_s++)if(graph[index_s].data == start)break;for(;index_e < current_count;index_e++)if(graph[index_e].data == end)break;// 两个顶点的下标找到了if(index_s == current_count||index_e == current_count)continue;// 添加关系Relation_t *rt = new Relation_t;rt->index = index_e;rt->weight = data;rt->next = nullptr;// 当至少存在出度顶点的时候if(graph[index_s].first){Relation_t *rt_ptr = graph[index_s].first;while(rt_ptr->next)rt_ptr = rt_ptr->next;// 存进关系链表rt_ptr->next = rt;}else{ // 一个出度结点都没有的时候graph[index_s].first = rt;}}return graph;
}void printrelation(Vertex_t *graph)
{if(!graph)std::cout << "空图" << std::endl;for(int count_v = 0;count_v < current_count;count_v++){std::cout << "顶点<"<< graph[count_v].data <<">:";Relation_t *rt_ptr = graph[count_v].first;while(rt_ptr){std::cout<< "<"<< graph[count_v].data <<","<< graph[rt_ptr->index].data <<">" << "("<<rt_ptr->weight<<")";rt_ptr = rt_ptr->next;}std::cout << std::endl;}
}// 计算下标
int getIndex(Vertex_t *graph,std::string vertex_v)
{for(int index = 0;index < current_count;index++){if(vertex_v == (graph[index]).data)return index;}return -1;
}/*逻辑:设初始化的时候,图中各个顶点均为被访问过。从图中某个顶点(V0)出发,访问V0,然后搜索V0的邻接顶点Vi,再以Vi为基础访问Vi的邻接顶点(依次下去...)(深度优先)。若某个顶点没有邻接顶点(邻接顶点均被访问完毕),则回溯到它上一个顶点,然后再从它的上一个顶点开始继续进行邻接顶点的访问,直到所有的顶点都被访问完毕。@brief 深度优先搜索算法@param graph 需要进行深度优先搜索的图指针
*/
void DFS(Vertex_t *graph,std::string v0)
{int v0_pos = getIndex(graph,v0);if(v0_pos == -1)return;// 标志位数组,且初始化所有顶点都为未被访问static bool *flags=new bool[current_count];// 访问V0std::cout << graph[v0_pos].data << " ";flags[v0_pos] = true;Relation_t *currnet_relation = graph[v0_pos].first;while(currnet_relation){// 递归下去进行访问if(flags[currnet_relation->index] == false)DFS(graph,graph[currnet_relation->index].data);// 递归结束返回,再次访问下一个邻接点currnet_relation = currnet_relation->next;}std::cout << std::endl;
}int main()
{Vertex_t *graph = creatGraph(10);DFS(graph,"A");delete []graph;return 0;
}
3、广度优先搜索算法
广度优先搜索算法(Breath First search)BFS
类似于树的层次遍历,初始化的时候,图中的各项顶点均未被访问,从图某个顶点开始(V0)依次的访 问V0的各个邻接点(广度优先)
然后分别冲这些被访问过的顶点出发,仍然按照广度优先的策略访问其他的顶点...直到所有能访问的顶 点均被访问完毕。
***BFS示例代码***
#include <iostream>
#include <cstring>
#include <queue>// 关系类型
typedef struct relation
{int index; // 下标int weight; // 权值struct relation *next; // 下一个关系的顶点的下标指针
}Relation_t;// 顶点类型
typedef struct
{std::string data; // 顶点数据Relation_t *first; // 该顶点的关系集
}Vertex_t;// 当前顶点数
int current_count = 0;/*@brief 创建一个图:邻接表@param count 该图的最大顶点数量 @return 成功返回创建好的图指针
*/
Vertex_t *creatGraph(int count)
{// 申请空间Vertex_t *graph = new Vertex_t[count];// 初始化memset(graph,0,sizeof(Vertex_t)*count);std::cout << "请输入顶点数据空格分开(“结束”输入):";// 接受顶点while(1){std::string data = "结束";std::cin >> data;if(data == "结束")break;if(current_count == count)break;// 新增顶点位置graph[current_count].data = data;graph[current_count].first = nullptr;current_count++;}// 增加关系while(1){std::cout << "请输入顶点关系(结束 结束 -1):";// 出发顶点和终止顶点 权值std::string start;std::string end;int data;std::cin >> start >> end >> data;if(start=="结束"||end=="结束"||data == -1)break;// 存储关系// 获取start和end在图数组的什么位置int index_s = 0,index_e = 0;for(;index_s < current_count;index_s++)if(graph[index_s].data == start)break;for(;index_e < current_count;index_e++)if(graph[index_e].data == end)break;// 两个顶点的下标找到了if(index_s == current_count||index_e == current_count)continue;// 添加关系Relation_t *rt = new Relation_t;rt->index = index_e;rt->weight = data;rt->next = nullptr;// 当至少存在出度顶点的时候if(graph[index_s].first){Relation_t *rt_ptr = graph[index_s].first;while(rt_ptr->next)rt_ptr = rt_ptr->next;// 存进关系链表rt_ptr->next = rt;}else{ // 一个出度结点都没有的时候graph[index_s].first = rt;}}return graph;
}void printrelation(Vertex_t *graph)
{if(!graph)std::cout << "空图" << std::endl;for(int count_v = 0;count_v < current_count;count_v++){std::cout << "顶点<"<< graph[count_v].data <<">:";Relation_t *rt_ptr = graph[count_v].first;while(rt_ptr){std::cout<< "<"<< graph[count_v].data <<","<< graph[rt_ptr->index].data <<">" << "("<<rt_ptr->weight<<")";rt_ptr = rt_ptr->next;}std::cout << std::endl;}
}// 计算下标
int getIndex(Vertex_t *graph,std::string vertex_v)
{for(int index = 0;index < current_count;index++){if(vertex_v == (graph[index]).data)return index;}return -1;
}/*逻辑:类似于树的层次遍历,初始化的时候,图中的各项顶点均未被访问,从图某个顶点开始(V0)依次的访问V0的各个邻接点(广度优先)然后分别冲这些被访问过的顶点出发,仍然按照广度优先的策略访问其他的顶点...直到所有能访问的顶点均被访问完毕。@brief 广度优先搜索算法@param graph 需要进行广度优先搜索的图指针
*/
void BFS(Vertex_t *graph,std::string v0)
{int v0_pos = getIndex(graph,v0);if(v0_pos == -1)return;// 搞个队列std::queue<int> q;// 入队V0q.push(v0_pos);// 标志位数组,且初始化所有顶点都为未被访问static bool *flags=new bool[current_count];// 访问V0flags[v0_pos] = true;int current_pos = v0_pos;while(q.size()){Relation_t *currnet_relation=graph[current_pos].first;// 当前关系是否存在 循环的作用:是将该顶点的所有边都入队while(currnet_relation){// 是否被访问过if(flags[currnet_relation->index] == false){q.push(currnet_relation->index);flags[currnet_relation->index] = true;}// 递归结束返回,再次访问下一个邻接点currnet_relation = currnet_relation->next;}// 出队,打印、标记current_pos = q.front();q.pop();std::cout << graph[current_pos].data << " ";}std::cout << std::endl;
}int main()
{Vertex_t *graph = creatGraph(10);BFS(graph,"A");delete []graph;return 0;
}