艺轫 发表于 5 天前

层序遍历重建二叉树,绘制二叉树图片

在力扣刷二叉树相关题目时,输入一般都是完全层序遍历,我习惯在自己电脑上调试代码,因此才编写下面代码将完全层序遍历数据重建二叉树对象。
生成的结果二叉树一般也只会给出完全层序遍历,无法直观的感受二叉树实际情况,因此我编写代码将二叉树对象生成svg图片,刷二叉树相关题目更清晰直观了。
力扣原题:https://leetcode.cn/problems/w6cpku/ ,效果图如下:

代码如下:
package main

import (
        "fmt"
        "math"
        "os"
        "strconv"
        "strings"
)

type TreeNode struct {
        Val   int
        Left*TreeNode
        Right *TreeNode
}

// 根据完全层序遍历构建二叉树
func buildTree(s string) *TreeNode {
        nums := strings.Split(strings.ReplaceAll(s, " ", ""), ",")
        if len(nums) == 0 {
                return nil
        }

        n, err := strconv.Atoi(nums)
        if err != nil {
                return nil
        }

        var (
                root= &TreeNode{Val: n}
                queue = []*TreeNode{root}
                i   = 1
        )
        for i < len(nums) {
                node := queue
                queue = queue
                if n, err = strconv.Atoi(nums); err == nil {
                        node.Left = &TreeNode{Val: n}
                        queue = append(queue, node.Left)
                }
                i++
                if i < len(nums) {
                        if n, err = strconv.Atoi(nums); err == nil {
                                node.Right = &TreeNode{Val: n}
                                queue = append(queue, node.Right)
                        }
                }
                i++
        }
        return root
}

// 生成完全层序遍历
func levelOrder(root *TreeNode) string {
        if root == nil {
                return ""
        }
        var (
                result strings.Builder
                queue= []*TreeNode{root}
        )
        for len(queue) != 0 {
                node := queue
                queue = queue
                if node == nil {
                        result.WriteString("null,")
                } else {
                        result.WriteString(strconv.Itoa(node.Val))
                        result.WriteByte(',')
                        queue = append(queue, node.Left)
                        queue = append(queue, node.Right)
                }
        }
        return strings.TrimRightFunc(result.String(), func(r rune) bool {
                return r == 'n' || r == 'u' || r == 'l' || r == ','
        })
}

// 生成二叉树的SVG图片
func generateSVG(root *TreeNode) string {
        var treeHeight func(*TreeNode) int
        treeHeight = func(root *TreeNode) int {
                if root == nil {
                        return 0
                }
                return max(treeHeight(root.Left), treeHeight(root.Right)) + 1
        }

        var (
                height = treeHeight(root)
                width= int(math.Pow(2, float64(height))) * 50

                draw func(node *TreeNode, x, y, level int)

                svg = &strings.Builder{}
        )
        fmt.Fprintf(svg, `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 %d %d">`, width, height*100)

        draw = func(node *TreeNode, x, y, level int) {
                if node == nil {
                        return
                }

                nextLevel := level + 1
                offset := int(math.Pow(2, float64(height-nextLevel-1))) * 50

                if node.Left != nil {
                        leftX := x - offset
                        leftY := y + 100
                        fmt.Fprintf(svg, `<line x1="%d" y1="%d" x2="%d" y2="%d" stroke="black" stroke-width="2" />`, x, y, leftX, leftY)
                        draw(node.Left, leftX, leftY, nextLevel)
                }

                if node.Right != nil {
                        rightX := x + offset
                        rightY := y + 100
                        fmt.Fprintf(svg, `<line x1="%d" y1="%d" x2="%d" y2="%d" stroke="black" stroke-width="2" />`, x, y, rightX, rightY)
                        draw(node.Right, rightX, rightY, nextLevel)
                }

                fmt.Fprintf(svg, `<circle cx="%d" cy="%d" r="20" fill="lightblue" />`, x, y)
                fmt.Fprintf(svg, `<text x="%d" y="%d" text-anchor="middle" dominant-baseline="middle">%d</text>`, x, y, node.Val)
        }

        draw(root, width/2, 50, 0)
        svg.WriteString(`</svg>`)
        return svg.String()
}

func main() {
        root := buildTree("4,1,6,0,2,5,7,null,null,null,3,null,null,null,8")

        svg := generateSVG(root)

        err := os.WriteFile("binary_tree.svg", []byte(svg), 0666)
        if err != nil {
                fmt.Println("Error writing to file:", err)
                return
        }

        fmt.Println("SVG file created successfully!")
}出处:https://www.cnblogs.com/janbar本文版权归作者和博客园所有,欢迎转载,转载请标明出处。喜欢我的文章请 [关注我] 吧。如果您觉得本篇博文对您有所收获,可点击 [推荐] 并 [收藏]
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 层序遍历重建二叉树,绘制二叉树图片