树 是一种常常用到的数据结构,用来模拟具备树状结构性质的数据集合。node
二叉树是一种更为典型的树状结构。如它名字所描述的那样,二叉树是每一个节点最多有两个子树的树结构,一般子树被称做“左子树”和“右子树”。数据结构
所谓的纵向遍历二叉树,一般指的是前序遍历、中序遍历、后序遍历。ide
下面会介绍这三种遍历中的递归写法与迭代写法。post
迭代写法就是用一个栈来存下每次遍历的左右子节点。this
假设树的定义以下:递归
// Definition for a binary tree node. function TreeNode(val, left, right) { this.val = (val===undefined ? 0 : val) this.left = (left===undefined ? null : left) this.right = (right===undefined ? null : right) }复制代码
前序遍历的顺序就是:根节点 -> 左子节点 -> 右子节点it
注意:栈是先入后出的,可是前序遍历是先遍历左子节点,再遍历右子节点,因此须要先把右子节点先入栈io
那么前序遍历的 递归写法 与 迭代写法 以下:function
// 递归 var preorderTraversal = functioån(root) { let arr = [] const preNode = (point) => { if (point) { arr.push(point.val) preNode(point.left) preNode(point.right) } } preNode(root) return arr }; // 迭代 var preorderTraversal = function(root) { let arr = [] let stack = [] if (root) stack.push(root) while (stack.length) { let point = stack.pop() arr.push(point.val) if (point.right) stack.push(point.right) if (point.left) stack.push(point.left) } return arr };复制代码
中序遍历的顺序就是:左子节点 -> 根节点 -> 右子节点class
那么中序遍历的 递归写法 与 迭代写法 以下:
// 递归 var inorderTraversal = function(root) { let arr = [] const midRoot = (point) => { if (point) { midRoot(point.left) arr.push(point.val) midRoot(point.right) } } midRoot(root) return arr }; // 迭代 var inorderTraversal = function(root) { let arr = [] let stack = [] while(root || stack.length) { while (root) { stack.push(root) root = root.left } root = stack.pop() arr.push(root.val) root = root.right } return arr };复制代码
后序遍历的顺序就是:左子节点 -> 右子节点 -> 根节点
这里解析一下后序遍历的迭代写法: 一样是用一个栈来存遍历的左右子节点,跟前序与中序遍历不同的是,这里我在存子节点的时候存多一个状态来记录,判断是否遍历过左右子节点了 默认是false,没有遍历过,当咱们遍历过以后设置为 true
那么后序遍历的 递归写法 与 迭代写法 以下:
// // 递归 var postorderTraversal = function(root) { let arr = [] const nextR = (point) => { if (point) { nextR(point.left) nextR(point.right) arr.push(point.val) } } nextR(root) return arr }; // 迭代 var postorderTraversal = function(root) { let arr = [] let stack = [] if (root) stack.push([root, false]) while(stack.length) { let point = stack.pop() if (point[1]) { arr.push(point[0].val) } else { if (!point[0].left && !point[0].right) { arr.push(point[0].val) } else { stack.push([point[0], true]) } if (point[0].right) stack.push([point[0].right, false]) if (point[0].left) stack.push([point[0].left, false]) } } return arr };复制代码
以上就是二叉树的纵向遍历的几种写法。后续会继续出二叉树的横向遍历的几种常见的场景以及写法。