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.放出源码
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可以用如下操作
< 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>