数据结构—树和二叉树-2.二叉树的层次遍历(BFS)
来源:互联网 发布:sql replace 去除空格 编辑:程序博客网 时间:2024/05/16 18:54
上一篇文章对二叉树做了一个简单的小练习,也是对二叉树有了一个大概的了解,接下来这一篇便是二叉树中即为关键的算法——二叉树的层次遍历,即BFS。
这个算法的重要性呢不再多说,主要用于求单源最短路径问题(无权值,即单权值的树)。
BFS——宽度优先遍历
顾名思义:先遍历完与初始状态最近的状态,然后再遍历与遍历完状态的最近的状态。从开始状态–>只需一次转移就到达的状态–>只需两次就到达的状态–>……..
如上一篇文章的二叉树
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
如果按照BFS如何遍历呢?
(1)从1开始遍历;(2)遍历与1最近的结点,即2和3;(3)遍历与2和3最近的结点,即4,5,6,7;(4)遍历与4,5,6,7最近的结点,即8,9,10,11,12,13,14,15。完成。
如何实现BFS?
答:队列。试想一下队列的特点——FIFO(先进先出),ok,那么我们模拟一下结点入队出队的过程。
(1)创建一个空队列q;
(2)将结点1入队;队列状态为:1
(3)循环(下面的步骤都在这个循环里完成),条件是判断队列q是否为空,因为如果所有结点都不再入队即遍历完成;
(4)取队头结点赋给新结点V,然后出队,即结点1出队,目前队列为空,结点V就是结点1;队列状态为:NULL
(5)找到与V相邻的所有结点,即结点2和3,然后入队;队列状态为:2 3
(6)取队头元素,即结点2,赋给V,然后出队;队列状态为:3
(7)找到与V相邻的所有结点,即结点4和5,然后入队:队列状态为:3 4 5
(8)。。。。。不再赘述过程
基本过程就是这样,求最短路(无权)的思路也是如此,每个结点有个dis值,表示从头结点开始到其中一个结点的最短距离。过程和上面基本一致,就是需要将所有结点的dis值先初始化为0,然后遍历到一个结点,就将此结点的dis等于它的父节点的dis+1。
-例题.树的层次遍历-UVA122
算法入门经典上给出一个例题,我们来分析一下。
问题描述:输入一个二叉树,然后从上到下从左到右的顺序输出各个结点的值。每个结点都按照从根结点到它的移动序列给出(L表示左,R表示右)。
样例输入:(11,LL) (7,LLL) (8,R) (5,) (4,L) (13,RL) (2,LLR) (1,RRR) (4,RR) ()
样例输出:5 4 8 11 13 4 7 2 1
这个题目的bfs就是按照我刚才整理的思路用队列来实现,其实我觉得难度在于如何按照题目要求进行输入,将结点保存起来。按照刘汝佳老师的代码进行分析。
#include<cstdio>#include<cstring> #include<queue>#include<vector>using namespace std;const int maxn = 256+10;struct Node{ bool have_value; int v;//用来保存结点值 Node *left,*right; Node():have_value(false),left(NULL),right(NULL){}};//定义一个结点结构体 Node* newnode(){ return new Node();}//创建新结点函数 char s[maxn];Node* root;bool failed;void addnode(int v,char* s){ int n = strlen(s); Node* u = root; for(int i=0;i<n;i++) { if(s[i]=='L') { if(u->left==NULL) u->left = newnode();//如果结点不存在,建立新结点 u = u->left;//往左走到达新建立的结点 } else if(s[i]=='R') { if(u->right==NULL) u->right = newnode(); u = u->right; } } if(u->have_value) failed = true;//已经赋值过,表明输入有误 u->v = v; u->have_value = true;//做标记 }bool read_input(){ failed = false; root = newnode(); for(;;) { if(scanf("%s",s)!=1) return false; if(!strcmp(s,"()")) break;//如果输入为"()",即输入结束,直接退出循环。 int v; sscanf(&s[1],"%d",&v);//将字符串中的结点值读取出来赋给V addnode(v,strchr(s,',')+1);//strchr函数是返回,首次出现的位置,然后插入结点 } return true; }bool bfs(vector<int>& ans){ queue<Node*> q; ans.clear();//每次遍历之前要先重置vector,即清空 q.push(root);//将根结点先放入队列中 while(!q.empty())//判断是否为空 { Node* u = q.front();q.pop();//取队头结点赋给u,并出队 if(!u->have_value) return false;//如果有结点没有赋值,则输入有误 ans.push_back(u->v);//将当期结点的值插入到向量中 if(u->left!=NULL) { q.push(u->left);//如果左子结点不为空,则将左子结点入队 } if(u->right!=NULL) { q.push(u->right); } } return true;} int main(){ vector<int> v; while(read_input()) { if(!bfs(v)) failed = 1; if(failed) printf("not complete\n"); else{ for(int i=0;i<v.size();i++) { if(i != 0) printf(" "); printf("%d", v[i]); } printf("\n"); } } return 0;}
这题价值还是非常大的,通过vector来保存遍历的结点值,一边遍历一边保存。
- 数据结构—树和二叉树-2.二叉树的层次遍历(BFS)
- 数据结构-层次遍历二叉树
- 数据结构 BFS层次遍历二叉树【C语言版本】
- 数据结构--二叉树--层次遍历二叉树(顺序遍历)
- 二叉树的层次遍历(BFS),二叉树的所有路径,二叉树的最大路径和(分治)
- 【数据结构】二叉树的层次遍历
- 【数据结构】二叉树的层次遍历2
- 白书练习 层次遍历 (二叉树的bfs)
- 数据结构 — 5.二叉树层次遍历
- 数据结构—二叉树层次遍历
- 数据结构和算法--二叉树的层次遍历
- 二叉树建立 以及 bfs层次遍历
- 初始BFS ,以及二叉树层次遍历
- 数据结构——二叉树的层次遍历
- 数据结构例程——二叉树的层次遍历算法
- 数据结构实验之求二叉树后序遍历和层次遍历(根据前序中序还原二叉树)
- 数据结构学习笔记(8)---二叉树的层次遍历
- 二叉树系列二:二叉树的层次遍历(BFS)
- 接下来两年,职业路线到底该怎么走
- 关于C++zhong #ifndef XXX_H #difine XXX_H #endif 那些事
- 数学黑洞
- C# 计时器开发
- AOP编程中注解参数详解
- 数据结构—树和二叉树-2.二叉树的层次遍历(BFS)
- spring注释配置及作用
- Atcoder AGC B Splatter Painting 记忆化+逆向模拟
- Docker学习记录(二)-Dockerfile创建镜像
- 图像分割算法源码
- [勇者闯LeetCode] 83. Remove Duplicates from Sorted List
- UVa OJ The Dole Queue 救济金发放 133
- 307. 范围求和队列
- java的数据类型