二叉树的几种遍历方式
二叉树遍历方法有:前序遍历、中序遍历、后序遍历
遍历如下二叉树:
树结点:
function TreeNode(x) { this.value = x this.left = null this.right = right }
前序遍历结果:ABDEGCF
function DLR(tree){ console.log(tree.value) if (tree.left) { DLR(tree.left) } if (tree.right) { DLR(tree.right) } }
中序遍历结果:DBGEACF
function LDR(tree){ if (tree.left) { LDR(tree.left) } console.log(tree.value) if (tree.right) { LDR(tree.right) } }
后序遍历结果:DGEBFCA
function LRD(tree){ if (tree.left) { LRD(tree.left) } if (tree.right) { LRD(tree.right) } console.log(tree.value) }
可以看到前序、中序、后序遍历的操作其实是一样的,只是取值操作的位置变了而已。
层次遍历结果:ABCDEFG
function levelTraversal(root){ if (!root) { return false } let result = [] // 用于存放最终结果的数组 let tree = [] // 用于存放遍历时产生的子树的队列 tree.push(root) while (tree.length) { let node = tree.shift() // 将第一个元素弹出队列 result.push(node.value) if (node.left) { tree.push(node.left) } if (node.right) { tree.push(node.right) } } return result }
根据前序遍历或中序遍历的结果还原二叉树:
function reConstructBinaryTree(pre, vin) { var res = null; if(pre.length===1){ res = { val: pre[0], left: null, right: null, } }else if(pre.length >1){ var root = pre[0]; var rootIndex = vin.indexOf(root); //记录根节点在中序遍历中的位置 var vinLeft = vin.slice(0,rootIndex); //分割中序遍历得到左子树 var vinRight = vin.slice(rootIndex+1,vin.length); //分割中序遍历得到右子树 pre.shift(); //去掉pre第一个元素并返回该元素。 var preLeft = pre.slice(0,vinLeft.length); var preRight = pre.slice(vinLeft.length,pre.length); res = { val: root, left: reConstructBinaryTree(preLeft,vinLeft), right: reConstructBinaryTree(preRight,vinRight), } } return res; }