网站首页 全球最实用的IT互联网站!

人工智能P2P分享Wind搜索发布信息网站地图标签大全

当前位置:诺佳网 > 软件工程 > 后端开发 > Go >

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

时间:2025-04-28 14:38

人气:

作者:admin

标签:

导读:在力扣刷二叉树相关题目时,输入一般都是完全层序遍历,我习惯在自己电脑上调试代码,因此才编写下面代码将完全层序遍历数据重建二叉树对象。 生成的结果二叉树一般也只会给出...

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

生成的结果二叉树一般也只会给出完全层序遍历,无法直观的感受二叉树实际情况,因此我编写代码将二叉树对象生成svg图片,刷二叉树相关题目更清晰直观了。

力扣原题:https://leetcode.cn/problems/w6cpku/ ,效果图如下:
image

代码如下:

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 本文版权归作者和博客园所有,欢迎转载,转载请标明出处。喜欢我的文章请 [关注我] 吧。 如果您觉得本篇博文对您有所收获,可点击 [推荐] [收藏]
温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信