算法:二叉树的层次遍历(递归实现+非递归实现,lua)
二叉树知识参考:深入学习二叉树(一) 二叉树基础
递归实现层次遍历算法参考:【面经】用递归方法对二叉树进行层次遍历 && 二叉树深度
上面第一篇基础写得不错,不了解二叉树的值得一看。
用递归来实现二叉树的层次遍历。lua实现
先上代码:
- function FindTree(tree, callback)
- local function Find(tree, level)
- if(tree == nil or level <= ) then
- return false;
- end
- if (level == ) then
- if callback then
- callback(tree.data);
- end
- return true;
- end
- local has_left = Find(tree.left, level - );
- local has_right = Find(tree.right, level - );
- return has_left or has_right;
- end
- local level = ;
- while Find(tree, level, callback) do
- level = level + ;
- end
- end
测试代码:
- a={};
- a.data = "a"
- b, c = {}, {}
- b.data = "b"
- c.data = "c"
- a.left = b
- a.right = c
- d, e, f, g = {}, {}, {}, {}
- d.data = "d"
- e.data = "e"
- f.data = "f"
- g.data = "g"
- b.left = d
- b.right = e
- c.left = f
- c.right = g
- h, i, j = {}, {}, {}
- h.data = "h"
- i.data = "i"
- j.data = "j"
- d.left = h
- d.right = i
- e.left = j
- local list = {}
- FindTree(a, function(data)
- table.insert(list, data)
- end)
- print(table.concat(list, ", "))
结果:
基本思路 (下面的a是测试树的根结点):
每步,都是一次从根到当前层级的自上而下的一次遍历,从上到下找到第1层a, 从上到下找到第2层b,c,从上到下找到第3层d,e,f,g
详细步骤:
1,FindTree(a, 1) : 如果此树深度大于等于1,a结点的data通过回调传回,函数返回true , while循环继续;如果深度为0,a==null,直接返回false,while循环结束。
2,FindTree(a, 2):如果此树深度大于等于2,传回a的子结点(上图b位置,或c位置,或bc位置)的data,返回true , while循环继续;如果深度小于2,返回false,while循环结束。
这里就比较复杂了,需要对函数递归有一定的了解。执行到 has_left = FindTree(tree.left, level - 1); 时,现场被保留(后续代码暂时不执行),程序再次进入到FindTree函数(即执行has_left = FindTree(b, 1)),当a有左子节点时,传回a的左子节点的data,返回true,即 has_left =true; 否则 has_left = false; 然后执行到has_right = FindTree(tree.right, level - 1); 同理,如果有右子节点,传回a的右子节点的data,返回true,即 has_right=true; 否则 has_right= false。如果a有左子节点或右子节点(或都有),整个函数返回true,while循环继续;如果a没有左结点和右结点,即深度小于2,has_left or has_right = false ,while循环结束。
3,FindTree(a, 3):如果此树深度大于等于3,传回a的深度为3的子结点(上图d, e, f, g的各位置随意组合)的data,返回true , while循环继续;如果深度小于2,返回false,while循环结束。
同理,执行到 has_left = FindTree(tree.left, level - 1); 时,现场保留,直到has_left = FindTree(tree.left.left, level - 1 - 1); 即has_left = FindTree(d, 1),如果d结点不存在,返回false,has_left = false; 如果存在,打印d结点的data,返回true,has_left = true; e, f, g各个位置 的检测同理。
4,…… , n - 1,
n,FindTree(a, n): 深度小于n (此树深度为n-1),返回false,while循环结束。
用非递归来实现二叉树的层次遍历。lua实现
先上代码:
- function FindTree2(tree, callback)
- local nodeList = {tree}
- while #nodeList > do
- local tempList = {}
- for i, v in ipairs(nodeList) do
- if callback then
- callback(v.data)
- end
- table.insert(tempList, v.left)
- table.insert(tempList, v.right)
- end
- nodeList = tempList;
- end
- end
测试代码:如上
测试如果:如上
基本思路:从上到下,每一层从左到右依次遍历。把每一层子节点存放在一个列表,直到这个列表为空,则遍历完成。
这个方式比较直观,直接看一下上面的图和代码,很容易理解。
算法:二叉树的层次遍历(递归实现+非递归实现,lua)的更多相关文章
- 二叉树前中后/层次遍历的递归与非递归形式(c++)
/* 二叉树前中后/层次遍历的递归与非递归形式 */ //*************** void preOrder1(BinaryTreeNode* pRoot) { if(pRoot==NULL) ...
- 数据结构二叉树的递归与非递归遍历之java,javascript,php实现可编译(1)java
前一段时间,学习数据结构的各种算法,概念不难理解,只是被C++的指针给弄的犯糊涂,于是用java,web,javascript,分别去实现数据结构的各种算法. 二叉树的遍历,本分享只是以二叉树中的先序 ...
- C实现二叉树(模块化集成,遍历的递归与非递归实现)
C实现二叉树模块化集成 实验源码介绍(源代码的总体介绍):header.h : 头文件链栈,循环队列,二叉树的结构声明和相关函数的声明.LinkStack.c : 链栈的相关操作函数定义.Queue. ...
- 二叉树3种递归和非递归遍历(Java)
import java.util.Stack; //二叉树3种递归和非递归遍历(Java) public class Traverse { /******************一二进制树的定义*** ...
- JAVA递归、非递归遍历二叉树(转)
原文链接: JAVA递归.非递归遍历二叉树 import java.util.Stack; import java.util.HashMap; public class BinTree { priva ...
- Java实现二叉树的先序、中序、后序、层序遍历(递归和非递归)
二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的.对于二叉树,有前序.中序以及后序三种遍历方法.因为树的定义本身就是递归定义,因此采用递归的方法去实现树的三种遍历不仅容易 ...
- 算法练习之二叉树的最大深度,二叉树的层次遍历 II
1.二叉树的最大深度 给定一个二叉树,找出其最大深度. 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数. 说明: 叶子节点是指没有子节点的节点. 示例:给定二叉树 [3,9,20,null,n ...
- 【面经】用递归方法对二叉树进行层次遍历 && 二叉树深度
void PrintNodeAtLevel(BiTree T,int level) { // 空树或层级不合理 ) return; == level) { cout << T->da ...
- lintcode : 二叉树的层次遍历
题目 二叉树的层次遍历 给出一棵二叉树,返回其节点值的层次遍历(逐层从左往右访问) 样例 给一棵二叉树 {3,9,20,#,#,15,7} : 3 / \ 9 20 / \ 15 7 返回他的分层遍历 ...
随机推荐
- CentOs7:ssh远程登录错误WARNING:REMOTE HOST IDENTIFICATION HAS CHANGED解决简单办法
错误及解决办法如下图所示. 第一步:cd ~/.ssh 第二步:vi known_hosts 第三步:删除与访问ip相关条目 附参考链接: https://www.cnblogs.com/york-h ...
- Redis 4.x RCE 复现学习
攻击场景: 能够访问远程redis的端口(直接访问或者SSRF) 对redis服务器可以访问到的另一台服务器有控制权 实际上就是通过主从特性来 同步传输数据,同时利用模块加载来加载恶意的用来进行命令执 ...
- 获取当前页面的webview ID
代码: A页面 <script type="text/javascript"> var ws = null; mui.plusReady(function(){ ws ...
- 我现在A函数开启事务,然后调用B函数,B函数中也开启了事务
有一点要知道,就是MYSQL不支持事务嵌套.所以PHP再包装,也是一个事务 laravel的事务嵌套,就是一个栈.事务A开启事务(真实开启)事务B开启事务(只是标记,并非真实开启了事务)事务B提交事务 ...
- 企业SOA架构案例分析
面向服务的架构(SOA)是一个组件模型,它将应用程序的不同功能单元(称为服务)进行拆分,并通过这些服务之间定义良好的接口和契约联系起来.接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台. ...
- leetcode25 K 个一组翻转链表
这道题关于链表的操作,中间指针操作略复杂. /** * Definition for singly-linked list. * struct ListNode { * int val; * List ...
- vsCoad设置代码自动换行
- 使用AWS、Docker与Rancher提供弹性的生产级服务
2017-07-26 开始想你的 RancherLabs AWS Summit 2017 Beijing已经圆满落幕啦!亚马逊公司首席技术官沃纳·威格尔博士莅临现场,分享 AWS 最新云解决方案,把握 ...
- Delphi ActionList详解
一个友好的用户界面,必须具有下拉菜单,弹出菜单,工具条和快捷键.同样一个功能,程序员可能要提供几种操作方式,如文本拷贝,菜单命令&Copy,快捷键Ctrl+C,工具条上的拷贝按钮,都是程序员提 ...
- Nginx+FastCGI到底是谁影响超时时间
需求: 一个php程序要跑一段时间,但是时间不确定. 问题: 当该php程序运行超过一段时间被强制断开连接. PHP本身超时处理 在 php.ini 中,有一个参数 max_execution_tim ...