Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/Musicminion/TreeVisualize-2021-SJTU-CS-Problem-Solution-and-Practice-Assignment


https://github.com/Musicminion/TreeVisualize-2021-SJTU-CS-Problem-Solution-and-Practice-Assignment

Last synced: about 1 month ago
JSON representation

Awesome Lists containing this project

README

        

### 树的可视化——开发者文档(v 3.0)

![,](https://ice.sjtu.edu.cn/api/attachments/2224800)

### 我应该如何启动项目?
- 您可能需要Visual Studio运行`.sln`文件才可以启动项目,我使用的版本是2022版
- 当然,您还需要安装`FLTK`才可以编译这个文件,我使用的版本是fltk-1.3.8,当然,FLTK的兼容性还是比较好的,所以版本并不会成为太大的问题
- 注意:您可能需要对项目属性做出一些修改,具体的配置过程请参考配置文末的FLTK文档。

### 小提示

助教/老师您好,本作业中的GUI相关的头文件经过了修改,所以烦请您在批阅作业时不要使用原先的GUI库,将本作品中GUI相关的一系列的头文件也一并导入到项目,或者直接运行问题解决方案,原先课程提供的GUI库存在以下问题的`bug` 列举如下(存在的bug全部都已经修复)

- 图形类的圆形不支持颜色填充(在本作品中已改正)
- In_box中`get string()` 函数异常,运行时会报错无法解析的外部符号,需要手动添加 `get string()` 的具体实现,但是 `get int()` 函数是可以正常工作的。(在本作品中已改正)
- `Vector_rec` 的逻辑混乱,功能具有局限性,特别是不支持清空数组,(事实上,我查看并检查了他的底层实现代码,发现它的析构函数对应的就是清空数组,所以问题存在诸多,为此我手动修改 GUI库里面的函数,增加了清空功能)(在本作品中已优化)
- `out_box` 类型在输出过程中只支持单行内容的输出,并且具有覆盖效应,修改之后的GUI库在输出时具有多行输出功能,可以自动刷新位置,使得最新的通知/消息可以及时的显示出来。同时,添加参数可以统计输入的函数(具体的实现就是修改了继承的方式/并且增添了一些附属功能与函数实现)
- 当然,由于能力和水平有限,程序在调试时使用的测试集也非常有限,从目前的的角度来看,保证没有任何的错误与 bug 不大可能,也无法肯定程序对于任何情况的输入都可以灵活应变并且处理,所以如果程序出现崩溃,极有可能是输入的树非法,如果遇到这种情况,请默认为树非法,并清空队列里面的所有文件,删除非法的文件并读取。
- 最后,感谢助教老师的评阅!

### 文件解释

- ReadMe 包括相关的开发文档与构图,屏幕像素的基本参数适配
- Program 包括测试样例与程序,您可以直接利用里面的`exe`程序测试
- Project 代码,您可以在这里审阅本作业的实现代码

### 按钮名词解释

- **清空数据** 清空所有队列中的文件
- **手动读取文件** 根据目录输入框中的目录,检索相关的文件
- **自动读取文件** 根据当前所在的目录,检索相关的文件
- **退出** 关闭程序
- **继续读取队列中的文件** 当文件超过2个时可以使用,每次读取队列中的两个文件,然后实现树的可视化。
- **查找匹配节点** 根据输入的节点名字匹配,并且高亮显示

### 程序的功能/特点

- 友好的操作界面与提示引导,回避了颜色的单一性
- 支持进度条的显示,实时跟踪任务的进程
- 支持文件的**自动读取**和**手动读取**,支持的文件包括 `.csv` `.in` `.txt` 等常见的OJ、文件输入的格式,既可以直接检索当前文件夹,也可以输入目录,直接检索目标文件夹
- 支持目录下的文件自动检索(同目录下的、但不支持文件夹,因为会递归消耗过多的空间导致`vector` 的容器崩溃,所以在3.0版本中我删除了递归功能,只检索文件)
- 支持基本信息的提示语引导
- 支持树的可视化,并适应与屏幕宽度或者大小,所有节点的位置可视化前实时计算,并调整。
- 回避了线段与节点遮挡的问题,利用数学方法计算,确保节点的连接线不会与节点的外框遮挡
- 支持同构的判断与信息提示和输出
- 支持文件自动化的连续读取(通过单击按钮实现阅读文件夹中的下一个树文件)为助教批阅作业节省时间
- 多种节点匹配方式供使用者选择
- 支持节点的高亮匹配(手动输入节点编号)
- 支持节点的自动高亮匹配(跟踪鼠标自动颜色变化,实时显示匹配节点)
- 支持多种类型的树,包括但不限于二叉树
- 支持非法树的报错,并且对于不同类型的错误有所区分。
- 对于不符合定义的树拒绝可视化,返回提示信息
- 对于严重非法(可能导致崩溃的输入)则会直接清空队列,并且初始化,避免出现崩溃
- 但对于普通的小错误输入,程序会忽略这个错误的输入,利用其他合法的输入完成可视化

### 更新记录

- 【2021-12-6】 完成程序的基本功能
- 【2021-12-7】 增加了响应式按钮 支持节点的自动高亮匹配(跟踪鼠标自动颜色变化)
- 【2021-12-7】 修正了部分文件读取的 bug,在空行读取时可以自动忽略
- 【2021-12-7】 修正了关于 GUI 库的一些bug
- 【2021-12-8】 优化了GUI库的`out_box` 功能,实现消息及时输出与显示的功能
- 【2021-12-8】 对全局的代码进行了修改,由于之前的设计是基于二叉树,与题目要求有出入。修改后,现在支持某节点有多个子节点的情况,但是考虑到一些节点会有两个父节点,所以这个问题有待修复
- 【2021-12-8】 加强了对非法树对鉴别机制,所有的函数采取 `try{}` 对报错机制,避免函数运行的时候出现崩溃。此外,容错机制增强,对于下列类型的非法错误的输入采取 **忽略** 的方式,不影响其他合法的输入或者可视化的进行,对于忽略的输入,信息屏幕上也会指出数量来。

```
-> // 空格类型的非法输入
-> // 父结点或者子节点不存在的输入
// 空白行输入
```

- 【2021-12-8】 优化了同构匹配的算法,优化了节点坐标的计算方法,使得结果更加适配显示屏幕。(目前已测试笔记本电脑常见`1080p`,`iPad` 显示屏幕,都可以正常运行且显示7行的可视化,没有字符重叠或者显示问题)
- 【2021-12-9】 更新了开发者文档
- 【2021-12-12】 更新了开发者文档

### 核心算法一:坐标刷新函数的计算

![,](https://ice.sjtu.edu.cn/api/attachments/2224801) ![,](https://ice.sjtu.edu.cn/api/attachments/2224818)

- 以上图的二叉树计算的为例,可视化区域一的范围是:

$${(x,y)∣0.135 \times x_{max} \le x \le 0.4325 \times x_{max},0\le y \le 0.9 \times y_{max}}$$

- 对于每一个节点,由于树不一定是二叉树,所以节点坐标用 `(m,n)` 其中 `m `代表行数,`n` 代表节点在所在行的排名
- 行数的计算显然可以用一个递归函数解决,相当于就是高度刷新函数
- `n` 节点在所在行的排名的计算可以通过队列实现,就是首先根节点入队,然后儿子节点入队,当队列不是空的时候,一直循环操作即可,把读取过程中,节点按照高度进入相应的容器。例如下图,队列中前面的一定在层中的左边 ![,](https://ice.sjtu.edu.cn/api/attachments/2224802)
- 依据节点的坐标,计算节点的 `xxScale` `yyScale` 就是说所在矩形的长与宽
- 依据上面计算的结果,计算节点所在矩形的中心

### 核心算法二:同构的判断实现

- 传入参数是左右树的根节点
- 如果左右子树都是空节点,那么认为同构
- 如果传入参数一个是空节点,一个是非空,一定不同构
- 否则,就尝试匹配左节点与右节点的所有儿子,匹配成功则返回真,否则就是假
- 匹配过程是递归函数

### 核心算法三:同构按钮的匹配

- 设计的匹配按钮继承了 `FL_Button` 同时成员还包括两个 `Circle` 指针
- `handle()` 函数解决鼠标的事件,一旦移动上来,就高亮显示匹配节点
- 匹配过程依赖于同构判断是建立的左树节点名字到右树节点名字的匹配

### 程序的架构

程序由以下的类组成,基本上每一个类都对应了其相应的 `.cpp ` `.h` 文件

- 课程提供的 `GUI` 一些抽象类的定义 例如 `Wedget`
- 课程提供的 `Graph` 完成绘图工作
- 课程提供的 `std_lib_facilities` 基本常用的库文件
- 课程提供的 `Window` 提供基本的窗口操作功能
- 自行编写的 `TreeVisulize` 完成可视化树的类
- 自行编写的 `WelcomeWindow` 完成引导与提示
- 自行编写的 `VisualizeMain` 完成可视化的核心工作
- 自行编写的 `MatchingButton` 完成按钮匹配的工作与监控鼠标的工作

### 补充

课程是利用给定的GUI库开发,给定的库是基于FLTK的,但是事实上想要完成这个大作业或者更好的完成大作业,直接使用FLTK我感觉一定是更优的解决方案。由于时间有限,课业与任务实属重大,从12月5日开始,两天完成了这个作业的基本功能,共计大概一千四百到六百行代码,可谓实属不易,后来由于最近数据结构题目做的有点多,导致满脑子都是二叉树,所以后来才发现需求是所有类型的树,导致进两千行代码全部作废,全部重新开始。完成这个新的项目(支持所有类型的树)是在周四,耗费时间一整天。总的来说,收货也真是满满(这大概是我目前写过最多的惹hh)当然作品也有很多遗憾,比如如果我可以较早的把程序的框架基于FLTK而不是课程给定的GUI库,再比如节点按钮的边缘略有一些影响美观……如果能改进这些问题,我相信无论是界面还是功能方面,都会有更大的优化。

关于FLTK的按钮,我也有一些想说的话,就是按钮的设计、形式有很多不足,回调函数我也是被困扰了许久,最终通过指针的方式,实现了按钮的匹配,可以说是这个大作业的一个难点吧。

最后,感谢老师批阅本作业,在结课之际,感谢老师的半学年以来的陪伴,新年之际,预祝老师新年快乐!