Skip to content

二叉树遍历(前序,后序,中序,层次)递归与迭代实现JavaScript #25

Open
@liusaint

Description

@liusaint

最近做leetcode题目。总结一下二叉树遍历的一般方法。

数据结构

function Node(val){
    this.left = this.right = null;
    this.val = val;
}

先定义一棵树。node1是根节点。

var node4 = {left: null, right: null, val: 4 }; 
var node5 = {left: null, right: null, val: 5 }; 
var node6 = {left: null, right: null, val: 6 }; 
var node7 = {left: null, right: null, val: 7 };
var node3 = {left: node6, right: node7, val: 3 };
var node2 = {left: node4, right: node5, val: 2 };
var node1 = {left: node2, right: node3, val: 1 };
  • 结构如图:
//     1
//    /\
//   2  3
//  /\  /\
// 4 5 6  7

什么是前中后序遍历?

以一个根节点带两个叶子节点举例。 根据访问的顺序,根节点在前面就是前序(根左右),在中间就是中序(左根右),在后面就是后续(左右根)。

1.前序遍历

  • 前序遍历递归实现:
function preorderTraversal(root) {
	if (!root) {
		return;
	}
	console.log(root.val);
	var left = root.left;
	var right = root.right;
	left && preorderTraversal(left);
	right && preorderTraversal(right);
}
preorderTraversal(node1); //1 2 4 5 3 6 7 
  • 前序遍历迭代实现:
function preorderTraversal1(root) {
	if (!root) {
		return;
	}
	var stack = [root];
	while (stack.length > 0) {
		//取第一个。
		var item = stack.shift();
		console.log(item.val);
		if (item.right) {
			stack.unshift(item.right);
		}
		if (item.left) {
			stack.unshift(item.left);
		}
	}
}
preorderTraversal1(node1); //1 2 4 5 3 6 7 

2.中序遍历

  • 中序遍历递归实现:
function inorderTraversal(root) {
	if (!root) {
		return;
	}
	var left = root.left;
	var right = root.right;
	left && inorderTraversal(left);
	console.log(root.val);
	right && inorderTraversal(right);
}

console.log(inorderTraversal(node1)); //4 2 5 1 6 3 7
  • 中序遍历迭代实现:
//中序遍历迭代方式。
function inorderTraversal1(root) {
	if (!root) {
		return;
	}
	var stack = [root];
	while (stack.length > 0) {

		var item = stack[stack.length - 1];

		if (!item.left || (item.left && item.left.isOk)) {
			stack.pop();
			item.isOk = true;
			console.log(item.val);
			item.right && stack.push(item.right);
		} else if (item.left && !item.left.isOk) {
			stack.push(item.left);
		}

	}
}

inorderTraversal1(node1); //4 2 5 1 6 3 7

3.后序遍历

  • 后序遍历递归实现:
function postorderTraversal(root) {
	if (!root) {
		return;
	}
	var left = root.left;
	var right = root.right;
	left && postorderTraversal(left);
	right && postorderTraversal(right);
	console.log(root.val);
}
postorderTraversal(node1);//4 5 2 6 7 3 1
  • 后序遍历迭代实现:
function postorderTraversal1(root) {
	if (!root) {
		return;
	}
	var stack = [root];
	while (stack.length > 0) {
		var item = stack[stack.length - 1];
		//满足这些就可以直接输出它了。它是叶子节点。或它的子节点都ok了。
		if ((item.left == null && item.right == null) || (item.left && item.left.isOk && item.right && item.right.isOk) || (item.left && item.left.isOk && item.right == null) || (item.left == null && item.right && item.right.isOk)) {
			item.isOk = true;
			console.log(item.val);
			stack.pop();
		} else if (item.left && !item.left.isOk) {
			//如果左边的没ok,就把左边的入栈
			stack.push(item.left);
		} else if (item.right && !item.right.isOk) {
			//如果右边的没ok就把右边的入栈。
			stack.push(item.right);
		}
	}
}
postorderTraversal1(node1);//4 5 2 6 7 3 1

4.层次遍历。

从上往下,从左往右,一层一层的遍历。

var levelOrder = function(root) {
	if(!root){
		return;
	}
	var checkArr = [root];
	while (checkArr.length > 0) {
		var newCheckArr = [];
		for (var i = 0; i < checkArr.length; i++) {
			var item = checkArr[i];
			console.log(item.val);
			item.left && newCheckArr.push(item.left);	
			item.right && newCheckArr.push(item.right);	
		}
		checkArr = newCheckArr;
	}
};
levelOrder(node1);//1 2 3 4 5 6 7

深度优先与广度优先

  • 二叉树的深度优先遍历的非递归的通用做法是采用栈,广度优先遍历的非递归的通用做法是采用队列。
  • 深度优先对每一个可能的分支路径深入到不能再深入为止,先序遍历、中序遍历、后序遍历属于深度优先。
  • 广度优先又叫层次遍历,从上往下,从左往右(也可以从右往左)访问结点,访问完一层就进入下一层,直到没有结点可以访问为止。

leetcode

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @liusaint

        Issue actions

          二叉树遍历(前序,后序,中序,层次)递归与迭代实现JavaScript · Issue #25 · liusaint/ls-blog