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

在力扣刷二叉树相关题目时,输入一般都是完全层序遍历,我习惯在自己电脑上调试代码,因此才编写下面代码将完全层序遍历数据重建二叉树对象。

生成的结果二叉树一般也只会给出完全层序遍历,无法直观的感受二叉树实际情况,因此我编写代码将二叉树对象生成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[0])
	if err != nil {
	return nil
	}
	var (
	root = &TreeNode{Val: n}
	queue = []*TreeNode{root}
	i = 1
	)
	for i < len(nums) {
	node := queue[0]
	queue = queue[1:]
	if n, err = strconv.Atoi(nums[i]); err == nil {
	node.Left = &TreeNode{Val: n}
	queue = append(queue, node.Left)
	}
	i++
	if i < len(nums) {
	if n, err = strconv.Atoi(nums[i]); 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[0]
	queue = queue[1:]
	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!")
}
作者:janbar原文地址:https://www.cnblogs.com/janbar/p/18851553

%s 个评论

要回复文章请先登录注册