美文网首页
Go语言实现二叉树遍历

Go语言实现二叉树遍历

作者: Venture_Mark | 来源:发表于2018-11-19 20:02 被阅读0次

    生成二叉树

    type Node struct {
        data  string
        left  *Node
        right *Node
    }
    
    nodeG := Node{data: "g", left: nil, right: nil}
    nodeF := Node{data: "f", left: &nodeG, right: nil}
    nodeE := Node{data: "e", left: nil, right: nil}
    nodeD := Node{data: "d", left: &nodeE, right: nil}
    nodeC := Node{data: "c", left: nil, right: nil}
    nodeB := Node{data: "b", left: &nodeD, right: &nodeF}
    nodeA := Node{data: "a", left: &nodeB, right: &nodeC}
    

    图例如下:

    btree

    结果应该是分别是:

    广度优先: a -> b -> c -> d -> f -> e -> g

    先序遍历: a -> b -> d -> e -> f -> g -> c

    中序遍历: e -> d -> b -> g -> f -> a -> c

    后序遍历: e -> d -> g -> f -> b -> c -> a

    广度优先遍历

    结果存在result里面,如果不存可以少一层变量

    func breadthFirstSearch(node Node) []string {
        var result []string
        var nodes []Node = []Node{node}
    
        for len(nodes) > 0 {
            node := nodes[0]
            nodes = nodes[1:]
            result = append(result, node.data)
            if (node.left != nil) {
                nodes = append(nodes, *node.left)
            }
            if (node.right != nil) {
                nodes = append(nodes, *node.right)
            }
        }
        return result
    }
    

    递归版前中后序遍历

    func preOrderRecursive(node Node) {
        fmt.Println(node.data)
        if node.left != nil {
            preOrderRecursive(*node.left)
        }
        // 在这里输出就是中序
        if node.right != nil {
            preOrderRecursive(*node.right)
        }
        // 在这里输出是后序
    

    非递归版遍历

    这个地方强烈建议读一下下面的第一个链接,我遵照着那篇文章实现的,只是用Go改写了而已。

    seqStack

    首先定义一个数据结构,用来存储一些Node的信息。

    type seqStack struct {
        data [100]*Node
        tag [100]int // 后续遍历准备
        top int // 数组下标
    }
    

    preOrder

    func preOrderLoop(node *Node) (result []string) {
        var s seqStack
        s.top = -1 // 空
        if node == nil {
            panic("no data here")
        }else {
            for node != nil || s.top != -1 {
                for node != nil {
                    result = append(result, node.data)
                    s.top++
                    s.data[s.top] = node
                    node = node.left
                }
                s.top--
                node = s.data[s.top + 1]
                node = node.right
            }
        }
        return
    }
    

    midOrder

    func midOrderLoop(node *Node) (result []string) {
        var s seqStack
        s.top = -1
        if node == nil {
            panic("no data here")
        }else {
            for node != nil || s.top != -1 {
                for node != nil {
                    s.top++
                    s.data[s.top] = node
                    node = node.left
                }
                s.top--
                node = s.data[s.top + 1]
                result = append(result, node.data)
                node = node.right
            }
        }
        return
    }
    

    postOrder

    这里是可以运行的,但是总会抛出一个数组越界的错误,我看了半天也没看出来哪里有问题,Mac版的devel我这边又有bug,没用起来。至少思路对了,我后面再看一下哪里的问题。(感谢 @RiXu 指正)

    func postOrderLoop(node *Node) (result []string)  {
        var s seqStack
        s.top = -1
    
        if node == nil {
            panic("no data here")
        }else {
            for node != nil || s.top != -1 {
                for node != nil {
                    s.top++
                    s.data[s.top] = node
                    s.tag[s.top] = 0
                    node = node.left
                }
    
                if s.tag[s.top] == 0 {
                    node = s.data[s.top]
                    s.tag[s.top] = 1
                    node = node.right
                }else {
                    for s.tag[s.top] == 1 {
                        s.top--
                        node = s.data[s.top + 1]
                        fmt.Println(node.data)
                        result = append(result, node.data)
                        if s.top < 0 {
                            break
                        }
                    }
                    node = nil
                }
            }
        }
        return
    }
    

    References

    相关文章

      网友评论

          本文标题:Go语言实现二叉树遍历

          本文链接:https://www.haomeiwen.com/subject/cgaafqtx.html