1.画出如下svg矢量图
G
1
1
2
0
1->2
3
2
1->3
4
4
2->4
5
0
2->5
8
6
4->8
9
7
4->9
14
3
8->14
10
1
5->10
6
4
3->6
7
5
3->7
11
6
6->11
12
5
6->12
13
4
7->13
2.放出源码
copy
package main
import (
"fmt"
"io"
"os"
"os/exec"
"strconv"
"strings"
)
func main () {
if len (os.Args) != 2 {
fmt.Printf("usage: %s \"1,0,2,4,0,4,5,6,7,1,null,6,5,4,nil,3\"\n" , os.Args[0 ])
return
}
const maxInt = 1 <<31 - 1
var arr []int
for _, v := range strings.Split(os.Args[1 ], "," ) {
str := strings.TrimSpace(v)
if str == "nil" || str == "null" {
arr = append (arr, maxInt)
} else if tmp, err := strconv.Atoi(str); err == nil {
arr = append (arr, tmp)
} else {
fmt.Println(err)
return
}
}
lArr := len (arr)
if lArr <= 0 {
return
}
var (
i, num = 0 , 2
head = &TreeNode{Val: arr[0 ], Num: 1 }
queue = []*TreeNode{head}
)
for len (queue) != 0 {
node := queue[0 ]
queue = queue[1 :]
if i++; i < lArr && arr[i] != maxInt {
node.Left = &TreeNode{Val: arr[i], Num: num}
queue = append (queue, node.Left)
num++
}
if i++; i < lArr && arr[i] != maxInt {
node.Right = &TreeNode{Val: arr[i], Num: num}
queue = append (queue, node.Right)
num++
}
}
printTree(head)
}
type TreeNode struct {
Val int
Num int
IsWrite bool
Left *TreeNode
Right *TreeNode
}
func printTree (root *TreeNode) error {
if root == nil {
return nil
}
const dotFile = "tree.dot"
fw, err := os.Create(dotFile)
if err != nil {
return err
}
fw.WriteString(`digraph G {
graph [nodesep=0.1]
node [shape=circle]
edge [arrowhead=vee]
` )
if root.Left != nil || root.Right != nil {
root.IsWrite = true
fmt.Fprintf(fw, " %d [group=%d,label=\"%d\"]\n" , root.Num, root.Num, root.Val)
}
printNode(fw, root)
fw.WriteString("}" )
fw.Close()
return exec.Command("dot" , dotFile, "-Tsvg" , "-o" +dotFile+".svg" ).Run()
}
func printNode (fw io.Writer, root *TreeNode) {
if !root.IsWrite {
fmt.Fprintf(fw, " %d [label=\"%d\"]\n" , root.Num, root.Val)
}
target, distance := 0 , 0
if root.Left != nil {
leftMax := root
leftDistance := 1
for leftMax.Right != nil {
leftMax = leftMax.Right
leftDistance++
}
target = leftMax.Num
distance = leftDistance
if root.Left.Left != nil || root.Left.Right != nil {
root.Left.IsWrite = true
fmt.Fprintf(fw, " %d [group=%d,label=\"%d\"]\n" , root.Left.Num, root.Left.Num, root.Left.Val)
}
fmt.Fprintf(fw, " %d -> %d\n" , root.Num, root.Left.Num)
printNode(fw, root.Left)
}
if root.Left != nil || root.Right != nil {
fmt.Fprintf(fw, " _%d [group=%d,label=\"\",width=0,style=invis]\n" , root.Num, root.Num)
fmt.Fprintf(fw, " %d -> _%d [style=invis]\n" , root.Num, root.Num)
}
if root.Right != nil {
rightMin := root.Right
rightDistance := 1
for rightMin.Left != nil {
rightMin = rightMin.Left
rightDistance++
}
if rightDistance <= distance {
target = rightMin.Num
distance = rightDistance
}
if root.Right.Left != nil || root.Right.Right != nil {
root.Right.IsWrite = true
fmt.Fprintf(fw, " %d [group=%d,label=\"%d\"]\n" , root.Right.Num, root.Right.Num, root.Right.Val)
}
fmt.Fprintf(fw, " %d -> %d\n" , root.Num, root.Right.Num)
printNode(fw, root.Right)
}
if distance > 1 && target != 0 {
fmt.Fprintf(fw, " {rank=same;_%d;%d}\n" , root.Num, target)
}
}
3. 总结
原理的话可以看【别人的解释 】
首先需要安装【graphviz 】
然后编写还原二叉树的代码,生成【graphviz】的脚本,然后用dot命令产生svg矢量图
在markdow编辑器中使用SVG可以用如下操作
copy
<div width="100%" style="overflow-x: auto;" >
<svg width ="140" height ="170" >
<title > SVG Sample</title >
<desc > This is a sample to use SVG in markdown on the website cnblogs.</desc >
<circle cx ="70" cy ="95" r ="50" style ="stroke: black; fill: none;" />
</svg >
</div>
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~