二叉树遍历顺序
四种遍历方式
先/前序遍历、中序遍历、后序遍历、层序遍历
测试二叉树创建
function BinaryTree() {
this.root = null;
this.insert = function (key) {
var node = new BinaryNode(key);
if (this.root) {
this._insertNode(node, this.root);
} else {
this.root = new BinaryNode(key);
}
}
this._insertNode = function (node, tree) {
if (node.key < tree.key) {
if (tree.left) {
this._insertNode(node, tree.left);
} else {
tree.left = node;
}
} else {
if (tree.right) {
this._insertNode(node, tree.right);
} else {
tree.right = node;
}
}
}
function BinaryNode(key) {
this.key = key;
this.left = null;
this.right = null;
}
}
var arr = [6, 3, 2, 10, 8, 12, 14];
var binaryTree = new BinaryTree();
arr.forEach(item => {
binaryTree.insert(item);
});
// console.log(binaryTree.root);
先/前序遍历
根左右-先访问根节点,然后左子树,最后右子树
结果是:6, 3, 2, 10, 8, 12, 14
/**
* BinaryNode {
* key: <Any>
* left: <BinaryNode>;
* right: <BinaryNode>;
* }
* @param {BinaryNode} tree
* @param {Array} arr
* @return {Array}
*/
function preorder(tree, arr = []) {
if (tree) {
arr.push(tree.key);
preorder(tree.left, arr);
preorder(tree.right, arr);
}
return arr;
}
/**
* BinaryNode {
* key: <Any>
* left: <BinaryNode>;
* right: <BinaryNode>;
* }
* @param {BinaryNode} tree
* @return {Array}
*/
function preorder(tree) {
let current = tree;
const tem = [];
const res = [];
while (current || tem.length) {
while (current) {
res.push(current.key);
tem.push(current);
current = current.left;
}
current = tem.pop().right;
}
return res;
}
中序遍历
左根右-先访问左子树,然后根节点,最后右子树
结果是:2, 3, 6, 8, 10, 12, 14
/**
* BinaryNode {
* key: <Any>
* left: <BinaryNode>;
* right: <BinaryNode>;
* }
* @param {BinaryNode} tree
* @param {Array} arr
* @return {Array}
*/
function middle(tree, arr = []) {
if (tree) {
middle(tree.left, arr);
arr.push(tree.key);
middle(tree.right, arr);
}
return arr;
}
/**
* BinaryNode {
* key: <Any>
* left: <BinaryNode>;
* right: <BinaryNode>;
* }
* @param {BinaryNode} tree
* @return {Array}
*/
function middle(tree) {
let current = tree;
const tem = [];
const res = [];
while (current || tem.length) {
while (current) {
tem.push(current);
current = current.left;
}
current = tem.pop();
res.push(current.key);
current = current.right;
}
return res;
}
后序遍历
左右根-先访问左子树,然后右子树,最后根节点
结果是:2, 3, 8, 14, 12, 10, 6
/**
* BinaryNode {
* key: <Any>
* left: <BinaryNode>;
* right: <BinaryNode>;
* }
* @param {BinaryNode} tree
* @param {Array} arr
* @return {Array}
*/
function after(tree, arr = []) {
if (tree) {
after(tree.left, arr);
after(tree.right, arr);
arr.push(tree.key);
}
return arr;
}
/**
* BinaryNode {
* key: <Any>
* left: <BinaryNode>;
* right: <BinaryNode>;
* }
* @param {BinaryNode} tree
* @return {Array}
*/
function after(tree) {
let current = tree;
let last;
const tem = [];
const res = [];
while (current || tem.length) {
while (current) {
tem.push(current);
current = current.left;
}
current = tem[tem.length - 1];
if (current.right && (current.right != last)) {
current = current.right;
} else {
current = tem.pop();
res.push(current.key);
last = current;
// 能走到这里的表示current没有左右子树或者已经放到res,所以设置为null,
// 不设置会导致第一个while重复遍历,if判断上面赋值current可能为undefined
current = null;
}
}
return res;
}
层序遍历
先根节点,然后从上往下每一层从左往右逐层
结果是:6, 3, 10, 2, 8, 12, 14
/**
* BinaryNode {
* key: <Any>
* left: <BinaryNode>;
* right: <BinaryNode>;
* }
* @param {BinaryNode} tree
* @param {Array} arr
* @param {Number} floor
* @return {Array}
*/
function level(tree, arr = [], floor = 0) {
if (tree) {
if (!arr[floor]) {
arr[floor] = [];
}
arr[floor].push(tree.key);
level(tree.left, arr, floor +1);
level(tree.right, arr, floor +1);
}
return arr;
}
/**
* @param {BinaryNode} tree
* @return {Array}
*/
function levelEach(tree) {
let res = [];
const levelArr = level(tree);
levelArr.forEach(item => {
res = [ ...res, ...item ];
});
// res = levelArr.flat();
return res;
}
/**
* BinaryNode {
* key: <Any>
* left: <BinaryNode>;
* right: <BinaryNode>;
* }
* @param {BinaryNode} tree
* @return {Array}
*/
function level(tree) {
const res = [];
if (!tree) return res;
let floor = 0;
let current = [tree];
while (current.length) {
let tem = [];
res[floor] = [];
current.forEach(item => {
res[floor].push(item.key);
if (item.left) {
tem.push(item.left)
}
if (item.right) {
tem.push(item.right)
}
});
floor++;
current = tem;
}
return res;
}
/**
* @param {BinaryNode} tree
* @return {Array}
*/
function levelEach(tree) {
let res = [];
const levelArr = level(tree);
levelArr.forEach(item => {
res = [ ...res, ...item ];
});
// res = levelArr.flat();
return res;
}
结语:
每种遍历提供两种方法,递归和非递归。层序遍历中第二个方法只为打平结果数组。