先序,中序,后序遍历二叉树,3个递归,1个递归,不用递归解法

实现二叉树先序,中序和后序遍历

http://www.nowcoder.com/questionTerminal/a9fec6c46a684ad5a3abd4e365a9d362

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 
}
全部评论

相关推荐

06-27 12:54
已编辑
门头沟学院 Java
累了,讲讲我的大学经历吧,目前在家待业。我是一个二本院校软件工程专业。最开始选专业是觉得计算机感兴趣,所以选择了他。本人学习计算机是从大二暑假结束开始的,也就是大三开始。当时每天学习,我个人认为Java以及是我生活的一部分了,就这样持续学习了一年半,来到了大四上学期末,大概是在12月中旬,我终于找的到了一家上海中厂的实习,但我发现实习生的工作很枯燥,公司分配的活也不多,大多时间也是自己在自学。就这样我秋招末才找到实习。时间来到了3月中旬,公司说我可以转正,但是转正工资只有7000,不过很稳定,不加班,双休,因为要回学校参加答辩了,同时当时也是心高气傲,认为可以找到更好的,所以放弃了转正机会,回学校准备论文。准备论文期间就也没有投递简历。然后时间来到了5月中旬,这时春招基本也结束了,然后我开始投递简历,期间只是约到了几家下场面试。工资也只有6-7k,到现在我不知道该怎么办了。已经没有当初学习的心劲了,好累呀,但是又不知道该干什么去。在家就是打游戏,boss简历投一投。每天日重一次。26秋招都说是针对26届的人,25怎么办。我好绝望。要不要参加考公、考研、央国企这些的。有没有大佬可以帮帮我。为什么感觉别人找工作都是顺其自然的事情,我感觉自己每一步都在艰难追赶。八股文背了又忘背了又忘,我每次都花很长时间去理解他,可是现在感觉八股、项目都忘完了。真的已经没有力气再去学习了。图片是我的简历,有没有大哥可以指正一下,或者说我应该走哪条路,有点不想在找工作了。
码客明:太累了就休息一下兄弟,人生不会完蛋的
如果实习可以转正,你会不...
点赞 评论 收藏
分享
评论
2
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务