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

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

生成的结果二叉树一般也只会给出完全层序遍历,无法直观的感受二叉树实际情况,因此我编写代码将二叉树对象生成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!")
}
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!")
}
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!") }

来源链接:https://www.cnblogs.com/janbar/p/18851553

© 版权声明
THE END
支持一下吧
点赞14 分享
评论 抢沙发
头像
请文明发言!
提交
头像

昵称

取消
昵称表情代码快捷回复

    暂无评论内容