欲买桂花同载酒,荒泷天下第一斗。|

janbar

园龄:4年6个月 粉丝:29 关注:10

2020-09-17 21:12 阅读 507 评论 0 推荐

根据层次遍历序列画出二叉树

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" ) /* 参考:https://blog.nanpuyue.com/2019/054.html */ 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) // 表示nil节点 } 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 // true表示已经将该节点序号和label写入文件 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++ } // 找到root节点的root.left往下最右边的节点 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) } // 生成root指向root.left的关系 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++ } // 找到root节点的root.Right往下最左边的节点 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) } // 生成root指向root.Right的关系 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. 总结

  1. 原理的话可以看【别人的解释
  2. 首先需要安装【graphviz
  3. 然后编写还原二叉树的代码,生成【graphviz】的脚本,然后用dot命令产生svg矢量图
  4. 在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>
posted @   janbar  阅读(507)  评论(0编辑  收藏  举报
编辑推荐:
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~

FAVOURITE

点击右上角即可分享
微信分享提示
*✧⁺˚⁺ପ(๑・ω・)੭ु⁾⁾ 好好学习天天向上
进入亮色模式
进入亮色模式

FAVOURITE