package main
import . "nc_tools"
/*
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
/**
*
* @param root TreeNode类 the root of binary tree
* @return int整型二维数组
*/
func threeOrders( root *TreeNode ) [][]int {
// write code here
var ans [][]int
// var L []int
// ans = append(ans, PreRoot(root, L))
// L = nil
// ans = append(ans, MidRoot(root, L))
// L = nil
// ans = append(ans, LastRoot(root, L))
ans = make([][]int, 3)
//ans[0],ans[1],ans[2] = PreMidLastRoot(root, ans[0],ans[1], ans[2])
ans[0], ans[1], ans[2] = PreMidLastRootStack2(root)
return ans
}
/* 普通解法,三个递归 */
func PreRoot(root *TreeNode, L []int) []int {
if(root == nil){
return L;
}
L = append(L, root.Val);
L = PreRoot(root.Left, L);
L = PreRoot(root.Right, L);
return L;
}
func MidRoot(root *TreeNode, L []int) []int {
if(root == nil){
return L;
}
L = MidRoot(root.Left, L);
L = append(L, root.Val);
L = MidRoot(root.Right, L);
return L;
}
func LastRoot(root *TreeNode, L []int) []int {
if(root == nil){
return L;
}
L = LastRoot(root.Left, L);
L = LastRoot(root.Right, L);
L = append(L, root.Val);
return L;
}
/* 递归升级,一次递归 */
func PreMidLastRoot(root *TreeNode, pre,mid, last []int)([]int,[]int,[]int){
if root == nil {
return pre, mid, last
}
pre = append(pre, root.Val)
pre,mid,last = PreMidLastRoot(root.Left, pre, mid, last)
mid = append(mid, root.Val)
pre,mid,last = PreMidLastRoot(root.Right, pre, mid, last)
last = append(last, root.Val)
return pre, mid, last
}
/* 不用递归,用栈模拟递归 */
func PreMidLastRootStack(root *TreeNode)(pre[]int,mid[]int,last[]int){
var stk1 []*TreeNode
var stk2 []int //stk1[i]对应的stk2[i], stk2[i]为 1:表示放入,前序; 2表示取出判断左子树, 3表示取出判断右子树
if root == nil {
return nil, nil, nil
}
//放入栈时,前序pre里加入Val
//第一次拿出看左子树时,pre加入左子树
//第二次拿出看右子树,mid加入。同时pre加入右子树
//最后一次拿出时, last加入
stk1 = append(stk1, root)
stk2 = append(stk2, 1)
pre = append(pre, root.Val)
for len(stk1) > 0 {
top := len(stk1) - 1
cur := stk1[top]
if stk2[top] == 1 {
stk2[top] = 2
if cur.Left != nil {
pre = append(pre, cur.Left.Val)
stk1 = append(stk1, cur.Left)
stk2 = append(stk2, 1)
}
}else if stk2[top] == 2 {
stk2[top] = 3
mid = append(mid, cur.Val)
if cur.Right != nil {
pre = append(pre, cur.Right.Val)
stk1 = append(stk1, cur.Right)
stk2 = append(stk2, 1)
}
} else {
last = append(last, cur.Val)
stk1 = stk1[:top]
stk2 = stk2[:top]
}
}
return
}
/* 不用递归,用栈模拟递归,使用1个栈。精简版*/
type Node struct {
Root *TreeNode
Mark int
}
func PreMidLastRootStack2(root *TreeNode)(pre[]int,mid[]int,last[]int){
var stk []Node
if root == nil {
return nil, nil, nil
}
//初始把root放入栈,makr = 1. pre,mid, last都为Nil
//第一次拿出时makr=1,val放入pre,同时看左子树不为Nil则加入栈。
//第二次拿出时mark=2,val放入mid,同时看右子树不为Nil则加入栈。
//第三次拿出时mark=3,val放入last,同时pop栈顶。因为左右子树都遍历过了。
//每次放入栈时,mark都是1.出栈时mark=3
stk = append(stk, Node{
Root: root,
Mark: 1,
})
for len(stk) > 0 {
top := len(stk) - 1
node := &stk[top]
if node.Mark == 1 {
node.Mark = 2
pre = append(pre, node.Root.Val)
if node.Root.Left != nil {
stk = append(stk, Node {
Root: node.Root.Left,
Mark: 1,
})
}
}else if node.Mark == 2 {
node.Mark = 3
mid = append(mid, node.Root.Val)
if node.Root.Right != nil {
stk = append(stk, Node {
Root: node.Root.Right,
Mark: 1,
})
}
}else {
last = append(last, node.Root.Val)
stk = stk[:top]
}
}
return
}