最近一直在刷二叉树题目,但在要验证结果时,通常用中序遍历、层序遍历查看结果,验证起来没有画图来得直观,所有想到自己动手制作二叉树的树形图。 直接开干,先从svg入手:

什么是SVG

SVG定义

SVG是可伸缩矢量图形 (Scalable Vector Graphics),于2003年1月14日成为 W3C 推荐标准。

SVG 用来定义用于网络的基于矢量的图形

SVG 使用 XML 格式定义图形

SVG 是万维网联盟的标准

SVG 与诸如 DOM 和 XSL 之类的 W3C 标准是一个整体

SVG优点

  • SVG 可被非常多的工具读取和修改(比如记事本)
  • SVG 与 JPEG 和 GIF 图像比起来,尺寸更小,且可压缩性更强。
  • SVG 图像在放大或改变尺寸的情况下其图形质量不会有所损失
  • SVG 图像可在任何的分辨率下被高质量地打印
  • SVG 可在图像质量不下降的情况下被放大
  • SVG 图像中的文本是可选的,同时也是可搜索的(很适合制作地图)
  • SVG 可以与 JavaScript 技术一起运行
  • SVG 是开放的标准
  • SVG 文件是纯粹的 XML

预定义元素

  • 矩形 <rect>
  • 圆形 <circle>
  • 椭圆 <ellipse>
  • 直线 <line>
  • 文字 <text>
  • 路径 <path>
  • 折线 <polyline>
  • 多边形 <polygon>

制作二叉树的树形图,就使用圆形、直线、文字三种即可:

圆形 <circle>

cx和cy属性定义圆点的x和y坐标;r属性定义圆的半径

如果省略cx和cy,圆的中心会被设置为(0, 0)

直线 <line>

x1,y2 属性定义线条的起始端点坐标

x2,y2 属性定义线条的结束端点坐标

文字 <text>

x,y 属性定义文字左对齐显示时的起始坐标(居中对齐则是文字中间点)

fill 属性定义文字的颜色

结点SVG格式

根结点

由<circle>和<text>组成,存放结点的数据域

子树结点

比根结点多出<line>元素,用来表示父结点左或右指针的指向

叶结点

与子树结点相同,为区别显示把<circle>填充色改为greenlight

结点坐标

坐标的确定

结点坐标确定,把二叉树还原成满二叉树,结点位置标记为:

[ [0,0], [1,0], [1,1], [2,0], [2,1], [2,2], [2,3], [3,0]......],再用循环计算出各点坐标。

连线的夹角

实际上不用考虑连线夹角,只要计算出连线始终两端点的坐标即可:

结点文本

以字符串形式保存好属性变量的特征关键词,用于遍历二叉树时替换成实际数据:

二叉树转SVG

遍历二叉树对应的满二叉树,读出数据域并计算坐标,转成svg格式:

格式转换

写入文件、调取浏览

全部源代码

至此,已达成自己的预想结果,算法实在有点笨拙,但总算成功了。