二叉树的递归遍历与非递归遍历-javascript



  1 function TreeNode(val) {  // 树节点构造方式
  2     this.val = val;
  3     this.left = null;
  4     this.right = null;
  5 }
  6
  7 function generateTree() {
  8     let root = new TreeNode(10);
  9     let left1 = new TreeNode(5);
 10     let left2 = new TreeNode(4);
 11     let left3 = new TreeNode(7);
 12     let right1 = new TreeNode(12);
 13     let right2 = new TreeNode(11);
 14     let right3 = new TreeNode(15);
 15     let right4 = new TreeNode(13);
 16     root.left = left1;
 17     left1.left = left2;
 18     left1.right = left3;
 19     root.right = right1;
 20     right1.left = right2;
 21     right1.right = right3;
 22     right3.left = right4;
 23     return root;
 24 }
 25
 26 function visit(node) {  // 遍历方式-打印出来
 27     console.log(node.val);
 28 }
 29
 30 // 递归方式
 31 // 前(先)序遍历递归方式
 32 function DLR_recursion(root) {
 33     root && visit(root);
 34     root.left && DLR_recursion(root.left);
 35     root.right && DLR_recursion(root.right);
 36 }
 37
 38 // 中序遍历递归方式
 39 function LDR_recursion(root) {
 40     root.left && LDR_recursion(root.left);
 41     root && visit(root);
 42     root.right && LDR_recursion(root.right);
 43 }
 44
 45 // 后序遍历递归方式
 46 function RDL_recursion(root) {
 47     root.left && RDL_recursion(root.left);
 48     root.right && RDL_recursion(root.right);
 49     root && visit(root);
 50 }
 51
 52 // 非递归方式
 53 // 前(先)序遍历非递归方式
 54 function DLR(root) {
 55     let arr = [];  // 维护一个栈
 56     root && arr.push(root);
 57     while (arr.length !== 0) {
 58         let temp = arr.pop();
 59         visit(temp);
 60         if (temp.right !== null) {  // 这里入栈顺序是先右后左,这样由于先进后出,所以符合右子树后出,为先序遍历
 61             arr.push(temp.right);
 62         }
 63         if (temp.left !== null) {
 64             arr.push(temp.left);
 65         }
 66     }
 67 }
 68
 69 // 中序非递归遍历
 70 function LDR(root) {
 71     let arr = [];
 72     while (true) {
 73         while (root !== null) {
 74             arr.push(root);
 75             root = root.left;
 76         }
 77         // 循环的结束条件是数组长度为0,遍历完成
 78         if (arr.length === 0) {
 79             break;
 80         }
 81         let temp = arr.pop();
 82         visit(temp); // 访问左子树的根节点
 83         root = temp.right; // 左子树的右子节点
 84     }
 85 }
 86
 87 // 后序非递归遍历(与前序遍历相反)
 88 function RDL(root) {
 89     let arr = [], res = [];
 90     root && arr.push(root);
 91     while (arr.length !== 0) {
 92         let temp = arr.pop();
 93         res.push(temp);
 94         if (temp.left !== null) {
 95             arr.push(temp.left);
 96         }
 97         if (temp.right !== null) {
 98             arr.push(temp.right);
 99         }
100     }
101     res.reverse();
102     res.forEach(item => visit(item));
103 }
104
105
106 function run() {
107     let tree = generateTree();
108     console.log("前(先)序递归遍历", DLR_recursion(tree));
109     console.log("前(先)序递归遍历", DLR(tree));
110
111     console.log("中序递归遍历", LDR_recursion(tree));
112     console.log("中序非递归遍历", LDR(tree));
113
114     console.log("后序递归遍历", RDL_recursion(tree));
115     console.log("后序非递归遍历", RDL(tree));
116
117 }
118
119 run();

结果输出:
前(先)序递归遍历:10,5,4,7,12,11,15,13
前(先)序非递归遍历:10,5,4,7,12,11,15,13
中序递归遍历:4,5,7,10,11,12,13,15
中序非递归遍历:4,5,7,1011,12,13,15
后序递归遍历:4,7,5,1113,15,12,10
后序非递归遍历:4,7,5,1113,15,12,10
 

原文地址:https://www.cnblogs.com/dyh-sjtu/p/9761583.html

时间: 2024-10-13 16:23:21

二叉树的递归遍历与非递归遍历-javascript的相关文章

二叉树高度,以及栈实现二叉树的先序,中序,后序遍历的非递归操作

求解二叉树的高度 树是递归定义的,所以用递归算法去求一棵二叉树的高度很方便. #include <iostream> #include <cstdio> using namespace std; struct Node { char data; Node *lchild; Node *rchild; }; void High(Node *T, int &h) { if (T == NULL) h = 0; else { int left_h; High(T->lchi

二叉树的递归遍历和非递归遍历(附详细例子)

mnesia在频繁操作数据的过程可能会报错:** WARNING ** Mnesia is overloaded: {dump_log, write_threshold},可以看出,mnesia应该是过载了.这个警告在mnesia dump操作会发生这个问题,表类型为disc_only_copies .disc_copies都可能会发生. 如何重现这个问题,例子的场景是多个进程同时在不断地mnesia:dirty_write/2 mnesia过载分析 1.抛出警告是在mnesia 增加dump

二叉树前序、后序和后序遍历(非递归实现)

二叉树前序.后序和后序遍历(非递归实现) (1)前序     我们知道,前序遍历的顺序是根左右,当根节点不为空时,该节点才可以被打印.目前书上常见对树的遍历都是采用递归的方法实现的,我们知道递归必然会产生中断,也就是有现场信息的保存,如果要实现非递归,那么我们必须自己要有一个栈,用来保存现场信息. 我先给出实现的伪代码,稍后我将解释为什么需要这么做,为何要用到这些条件. 伪代码如下: 1 void PreOrderTraverse(BinaryTree root) 2 { 3    Binary

二叉树基本操作续二:前序、中序、后序遍历(非递归 迭代方式)

这里给出二叉树三种遍历方式的迭代实现代码.二叉树的递归实现使用系统栈入栈出栈,而非递归的迭代实现方法就是手动维护一个栈,来模拟递归的入栈出栈过程. 本文没有给出用户栈的代码,如果需要结合上篇的测试代码一起测试,则需要自己实现自己的栈,以及基本的pop.push等栈操作函数. 前序迭代遍历: 1 void iter_preorder(tree_pointer ptr) 2 { 3 //前序遍历:先遍历根节点,然后再分别遍历左右子树 4 int top = -1; 5 tree_pointer st

二叉树非递归先中后序遍历 及 非递归交换二叉树两个孩子的位置

看到一个非递归交换一个二叉树的左右孩子的位置,于是想实现之,才发现非递归的先中后序遍历都忘记了……于是杂七杂八的写了一些,抄抄资料就实现了,然后实现非递归交换两个孩子的位置还是相当容易的.先直接上代码吧,其实这东西还是得自己写写过一遍的,印象才会更加深刻: #include <iostream> #include <fstream> #include <string> #include <stack> using std::cout; using std::

【数据结构与算法】二叉树深度遍历(非递归)

据说这个笔试面试的时候非常easy考到,所以写到这里. 图示 代码实现 /** * 源代码名称:TreeIteratorNoRecursion.java * 日期:2014-08-23 * 程序功能:二叉树深度遍历(非递归) * 版权:[email protected] * 作者:A2BGeek */ import java.util.Stack; public class TreeIteratorNoRecursion { class TreeNode<T> { private T mNod

二叉树前序、中序和后序遍历的非递归实现

1 二叉树的前序遍历 对于每棵子树,先处理根,然后处理左子树,最后处理右子树.根最先访问,所以是前序遍历. 2 二叉树的中序遍历 对于每棵子树,先处理左子树,然后处理根,最后处理右子树.根中间访问,所以是中序遍历. 3 二叉树的后序遍历 对于每棵子树,先处理左子树,然后处理右子树,最后处理根.根最后访问,所以是后序遍历. 4 二叉树后序遍历的非递归实现 如果pre为NULL: 左右儿子都是NULL,那么自己出栈: 如果左儿子为NULL,右儿子不为NULL,右儿子进栈: 如果左儿子不为NULL,那

c/c++二叉树的创建与遍历(非递归遍历左右中,破坏树结构)

二叉树的创建与遍历(非递归遍历左右中,破坏树结构) 创建 二叉树的递归3种遍历方式: 1,先中心,再左树,再右树 2,先左树,再中心,再右树 3,先左树,再右树,再中心 二叉树的非递归4种遍历方式: 1,先中心,再左树,再右树 2,先左树,再中心,再右树 3,先左树,再右树,再中心 4,层级遍历 二叉树的查找,求高度,求个数,求父节点,复制二叉树,释放二叉树 编译方法,用gcc编译不过去,用g++编译,命令如下: g++ -g nodestack.c nodequeue.c bintree.c

二叉树先序遍历(非递归)

二叉树的先序遍历(非递归)特别简单 直接上代码,根节点先入栈,然后循环栈不为空,pop出来后让右节点和左节点分别入栈 # Definition for a binary tree node. # class TreeNode(object): # def __init__(self, x): # self.val = x # self.left = None # self.right = None class Solution(object): def preorderTraversal(sel

二叉树的遍历--递归实现与非递归实现

二叉树的表示 在研究二叉树的遍历之前,我们需要先看看二叉树的表示方式. 一般来说,我们使用自定义的数据结构或是数组来表示二叉树. 二叉树的数据结构: public class TreeNode { public int val; // 左孩子 public TreeNode left; // 右孩子 public TreeNode right; } 数组形式表现二叉树 当我们使用数组形式表现二叉树时,我们将数组第一个节点的索引置为「1」,也就是根节点,如果我们通用性的将其当为「x」,那么它的左孩