算法入门之二叉树遍历顺序

2 篇文章 0 订阅

二叉树遍历顺序

四种遍历方式

先/前序遍历、中序遍历、后序遍历、层序遍历

测试二叉树创建

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;
}
结语:

每种遍历提供两种方法,递归和非递归。层序遍历中第二个方法只为打平结果数组。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值