js中的两叉树遍历

js中的两叉树遍历
二叉树是由左、右子树的根。左边和朋友分别是一棵二叉树。

本文主要实现JS中两叉树的遍历。

两叉树的一个例子

var树{ {
值:1,
左:{
值:2,
左:{
价值:4
}
},
右:{
值:3,
左:{
值:5,
左:{
价值:7
},
右:{
价值:8
}
},
右:{
价值:6
}
}
}
广度优先搜索

宽度优先遍历从两叉树的第一层(根节点)开始。它从上到下逐层遍历。在同一层中,我们从左到右依次访问每个节点。

实现uff1a
使用数组模拟队列。根节点首先放在队列中。当队列不为空时,执行循环:取出队列中的一个节点。如果节点的左子树不是空的,那么节点的左子树将被输入到队列中。如果节点的右子树是非空的,那么节点的右子树将进入队列。

(描述有点不清楚,只看代码)。
无功levelordertraversal =功能(节点){
如果(!结){
把新的错误(空树)
}
var { }
Que.push(节点)
而(que.length!= 0){
节点= que.shift()
console.log(节点值)
如果(节点。左)que.push(节点。左)
如果(节点。右)que.push(节点。右)
}
}
递归遍历

认为在这些字母中递归遍历的三种方法是好的:

d:访问根节点,l:遍历根节点的左子树,r:遍历根节点的右子树。

前序遍历:DLR

中序遍历:LDR

后序遍历:LRD

字母按字母顺序排列的意思是

这3个遍历是递归遍历,或深度优先搜索,DFS,因为它是总的。

这是深度访问的一个优先事项。

前序遍历的递归算法:

VaR序=功能(节点){
如果(节点){
console.log(节点值);
序(节点。左);
序(节点。右);
}
}
序遍历的递推算法:

函数(节点){
如果(节点){
中(左节点);
console.log(节点值);
中(节点,右);
}
}
后序遍历的递归算法:

VaR后序=功能(节点){
如果(节点){
PostOrder(节点。左);
PostOrder(节点。右);
console.log(节点值);
}
}
非递归深度优先遍历

事实上,我不太清楚这些概念是属于谁的,在有些书中,两叉树的遍历只讲述了上述三种递归遍历,有些被分成两类:广度优先遍历和深度优先遍历。递归遍历分为深度遍历。其中有些是递归遍历和非递归遍历。递归遍历有两种,一种是广度优先遍历,另一种是遍历。

队列只是在广度优先遍历中使用,因此在非递归深度优先遍历中使用堆栈,在JS中使用数组进行模拟。

这是唯一的前序:

我试着描述这个算法,但是我没有很清楚地描述它,你必须从代码的角度去理解它。
无功preorderunrecur =功能(节点){
如果(!结){
把新的错误(空树)
}
var堆栈{ }
Stack.push(节点)
而(stack.length!= 0){
节点= stack.pop()
console.log(节点值)
如果(节点。右)stack.push(节点。右)
如果(节点。左)stack.push(节点。左)
}
}
考虑到这一点,找到了一个非递归算法,因此在这里补充了非递归遍历方法。

非递归中间顺序

首先,将数字的左节点推入堆栈,然后取出,然后推右节点。
无功inorderunrecur =功能(节点){
如果(!结){
把新的错误(空树)
}
var堆栈{ }
而(stack.length = =结{ 0 | |!)
如果(节点){
Stack.push(节点)
节点= node.left
{人}
节点= stack.pop()
console.log(节点值)
节点= node.right
}
}
}
非递归后序(使用堆栈)

临时变量用于记录最后一个堆栈/堆栈的节点,其思想是首先将根节点和左边树推入堆栈,然后取左边的树,然后推右边的树,取出,最后取脚跟节点。
无功posorderunrecur =功能(节点){
如果(!结){
把新的错误(空树)
}
var堆栈{ }
Stack.push(节点)
var = null
而(stack.length!= 0){
TMP = { 1 } stack.length堆栈
如果(tmp.left节点tmp.left节点!= =!= TMP,右){
Stack.push(TMP。左)
如果(tmp.right结别的}!= TMP,右){
Stack.push(TMP,右)
{人}
console.log(stack.pop()。值)
节点= TMP
}
}
}
非递归后序(使用两个堆栈)

这个算法的思想与上面的相似,S1有点像临时变量。
无功posorderunrecur =功能(节点){
如果(节点){
var
var
s1.push(节点)
而(s1.length!= 0){
节点= s1.pop()
s2.push(节点)
如果(节点左){
s1.push(节点。左)
}
如果(节点右){
s1.push(节点。右)
}
}
而(s2.length!= 0){
console.log(s2.pop()。值);
}
}
}
Morris遍历

这意味着三个深度遍历是不带递归或堆栈实现的,空间复杂度是O(1)(我对org的概念不是特别清楚)。

(我先把这三种算法放在一起,我有时间再研究一下)

Morris Preface:
无功morrispre =函数(头){
如果(!头){
返回
}
无功cur1 =头,
电流= null
而(cur1){
电流= cur1.left
如果(研究){
而(cur2.right cur2.right!= cur1){
电流= cur2.right
}
如果(!研究。右){
cur2.right = cur1
console.log(cur1。值)
cur1 = cur1.left
继续
{人}
cur2.right = null
}
{人}
console.log(cur1。值)
}
cur1 = cur1.right
}
}
Morris:
无功morrisin =函数(头){
如果(!头){
返回
}
无功cur1 =头,
电流= null
而(cur1){
电流= cur1.left
如果(研究){
而(cur2.right cur2.right!= cur1){
电流= cur2.right
}
如果(!研究。右){
cur2.right = cur1
cur1 = cur1.left
继续
{人}
cur2.right = null
}
}
console.log(cur1。值)
cur1 = cur1.right
}
}
Morris邮政汇票:
无功morrispost =函数(头){
如果(!头){
返回
}
无功cur1 =头,
电流= null
而(cur1){
电流= cur1.left
如果(研究){
而(cur2.right cur2.right!= cur1){
电流= cur2.right
}
如果(!研究。右){
cur2.right = cur1
cur1 = cur1.left
继续
{人}
cur2.right = null
printedge(cur1。左)
}
}
cur1 = cur1.right
}
printedge(头)
}
无功printedge =函数(头){
以上是本文的全部内容,希望能对大家有所帮助。
免责声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕。
相关文章
返回顶部