设计目标: 图
设计思路:
看数据结构教材,明确图的数据结构的一些知识
图的抽象数据类型:
ADT Graph{
数据对象V:相同特性的数据元素的集合, 即顶点集
数据关系R:
R={VR}
VR={<v,w>|v,w属于V且P(v,w),<v,w>表示从v到w的弧, 谓词P<v,w>定义<v,w>的意义及信息}
基本操作P:
createGraph(V,VR);//按照顶点集V和弧集的定义来构造图G
locateVex(u);//返回顶点u在图G中的位置
getVex(v);//返回图中某顶点的值
putVex(v,value);//对图中某顶点赋值
firstAdjVex(v);//返回某顶点的第一个邻接顶点
nextAdjVex(v,w);// 若w是v的邻接顶点,则返回v相对于w的下一个邻接结点
insertVex(v);//在图中添加新顶点
deleteVex(v);//删除v顶点及其相关弧
dfsTraverse();//对图进行深度有限遍历
bfsTraverse();对图进行广度优先遍历
}ADT Graph
存储结构:
-
邻接矩阵(数组表示)
- 用2个数组分别存储 数据元素(顶点) \ 数据元素之间的关系(边\弧) 的信息;
- 用1 个二维数组表示邻接矩阵 , 存入连接两顶点的边(1\0); 网则存入权值;
- 压缩对称的无向图;
-
邻接表(链式结构)
- 每个顶点建立一个单链表, 其中的结点表示依附于该顶点的边;
- 每个结点需要存储与该顶点邻接的顶点在图中的位置\弧的相关信息;
- 每个链表应有一个表头结点, 存储该顶点的名(或其他信息)\指向链表中的第一个结点;
图的遍历:
-
深度优先搜素
- 从一个顶点出发, 访问此顶点, 再从未被访问的邻接顶点开始深度优先遍历, 直至所有顶点均被访问; (邻接顶点未被访问, 则访问;否则回溯)
- 实质上是对每个顶点查找其邻接顶点的过程;
- 可用递归实现;
- 需要设置标志数组判断某顶点是否被访问;
-
广度优先搜索
- 从一个顶点出发, 依次访问其未被访问的邻接顶点 ,再依次访问它们的邻接点;
- 先访问的邻接顶点的邻接顶点先访问, 可以通过队列存储访问的顶点;
设计过程:
首先创建顶点类Vertex, 有三个基本属性 序号\标签\携带的信息;携带的信息种类不定, 使用了泛型;重写了toString()方法便于打印输出;
然后根据顶点编织图的类Graph, 采用邻接矩阵的存储方式, 并设定顶点数最大值;
添加顶点表, 及跟踪末尾顶点(或是顶点数) 的变量, 主要用于操作顶点表;
完成构造函数, 初始化顶点表及邻接矩阵;
添加各类关于顶点及邻接顶点的方法, 与构造图时添加边的方法;
添加两个遍历方法;
在遍历方法时要用到栈和队列, 就用arrayLsit
简单构建了两个类;
然后便是对图的测试, 同时完善了许多考虑不周到的地方, 也仍有许多新产生的问题;
遇到的困难或问题
-
报错: 不是封闭类;
解决:
内部类非静态且需要外部实例, 最简单的解决办法是将其及其嵌套类变为静态(static);
-
如何将数组封装的类中?
添加一个private变量跟踪记录数组记录到的位置, 并在该类的构造函数中对其进行初始化;
-
构造函数中参数名和类变量名相同时会出现赋值失败的情况;
解决:
更改参数名, 或使用
this.
明确是对类变量赋值, 避免出现自己调用自己的情况; -
Java中如何销毁一个对象?
解决:将对象赋值为null, 使其与对应的内存失去联系, 会被垃圾回收器自动回收;
-
数组的快速复制?
使用
System.arraycopy();
public static native void arraycopy(Object src, int srcPos, Object dest, int destPos,int length);
但在处理多维数组时似乎有点问题;
-
git上传时总是会包含所有文件, 如何只上传必要文件?
使用
.gitignore
文件配置git上传时忽略的文件; -
配置了
gitignore
但是idea仍然上传所有文件;解决:
需要先清除缓存,项目文件夹中打开git bash,输入:
git rm -r --cached . git add . git commit -m 'update .gitignore'
多次尝试发现在idea中下方终端运行这几段代码不能起作用, 只能清空idea的git上传列表;