最近一直在刷二叉树题目,但在要验证结果时,通常用中序遍历、层序遍历查看结果,验证起来没有画图来得直观,所有想到自己动手制作二叉树的树形图。 直接开干,先从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格式:
格式转换
写入文件、调取浏览
全部源代码
至此,已达成自己的预想结果,算法实在有点笨拙,但总算成功了。