1. 递归版
function TreeNode(x) {
this.value = x;
this.left = null;
this.right = null;
}
- 先序遍历
var val1 = [];
function preOrderRecur(head) {
if(head===null) {
return;
}
//打印顺序为根左右
val1.concat(head.value);
preOrderRecur(head.left);
preOrderRecur(head.right);
}
- 中序遍历
var val2 = [];
function inOrderRecur(head) {
if(head===null) {
return;
}
inOrderRecur(head.left);
val2.concat(head.value);
inOrderRecur(head.right)
}
- 后序遍历
var val3 = [];
function posOrderRecur(head) {
if(head===null) {
return;
}
posOrderRecur(head.left);
preOrderRecur(head.right);
val3.concat(head.value)
}
2. 非递归版
- 先序遍历
总体思路为先准备一个栈,然后将头节点压入栈中,在while
循环中条件为该栈不为空,则将弹出的第一个节点作为头节点,并且该头节点右孩子不为空,压入栈中,左孩子不为空压入栈中,继续循环判断,大家最好画个图理解一下。
function preOrderUnRecur(head) {
var result = [];
if(head!==null) {
//准备一个栈
var stack = [];
stack.push(head);
while(stack.length!==0) {
//如果该栈不为空的话,从栈中弹出的节点作为head
head = stack.pop();
result.concat(head.value);
//如果该head右孩子不为空,先压入右孩子
if(head.right!==null) {
stack.push(head.right);
}
//如果该head左孩子不为空,压入左孩子
if(head.left!==null) {
stack.push(head.left);
}
}
return stack;
}
}
- 中序遍历
体思路就是准备一个栈,然后while
循环中条件为栈不为空或者是头节点不为空。如果头节点不为空,就将当前头节点压入栈中,并且新的头节点指向head.left
;如果头节点为空,就往出pop
,pop
出的节点作为头节点,并打印值,该head.right
作为新的头节点。
function inOrderUnRecur() {
var result = [];
if(head!==null) {
var stack = [];
while(stack.length!==null || head!==null) {
if(head!==null) {
stack.push(head);
head = head.left;
} else {
head = stack.pop();
result.concat(head.value);
head = head.right;
}
}
}
return result;
}
- 后序遍历
后序遍历二叉树的思想巧妙地借鉴了先序遍历的思想,准备两个辅助栈,第一个实现“根右左”的顺序,压入到第二个辅助栈中,将第二个栈中的数都弹出即为“左右根”的顺序。
function posOrderUnRecur1(head) {
var stack1 = [],
stack2 = [],
result = [];
if(head!==null) {
stack1.push(head);
while(stack1.length!==0) {
head = stack1.pop();
stack2.push(head);
if(head.left!==null) {
stack1.push(head.left)
} else if(head.right!==null) {
stack1.push(head.right)
}
}
//然后将stack2中的数据弹出,即为左右根的顺序
while(stack2!==null) {
result.concat(stack2.pop().value)
}
}
return result;
}