对图进行遍历的时候很希望拥有一个类似Scanner类中的hasNext()和next()函数对自己的类进行遍历。下面以图的邻接表储存方式为例,介绍一种比较粗糙的hasNext()和next()函数的实现。
图中结点的定义如下:
class Vertex {
char label; //图结点的值,唯一
Edge firstArc; //邻接的第一条弧
}
我希望能在Vertex类中创建一个hasNextArc()函数来判断是否存在以此结点为尾的弧,并且还能用一个nextArc()函数返回当前所指向的弧,功能和Scanner类中的hasNext()和next()函数类似。很自然的想法就是在Vertex类中添加一个私有类的工作指针p指向firstArc域,用hasNextArc()来判断p是否为null,hasNext()用来返回p并且p指向下一个结点。代码如下:
class Vertex {
char label; //图结点的值
Edge firstArc; //邻接的第一条弧
private Edge p; //工作指针
public boolean hasNextArc(){
if(p!=null)
return true;
else
return false;
}
public Edge nextArc(){
Edge re=p;
p=p.nextArc;
return re;
}
}
但是在图的实际使用上这种方式是行不通的,因为图刚建立起来的时候某些结点可能根本没有弧,那么firstArc域是为null的,那么如果对p初始化为firstArc域,那么p永远就是null。而图的使用过程中,结点是完全有可能添加弧的。所以对p的赋值应该也是个动态的过程,我选择在调用hasNextArc()函数的时候对p进行赋值。为了正确对p赋值,引入了另外一个private的布尔量pt,初始化为false。用来表示是否是第一次调用hasNextArc()。代码如下:
class Vertex {
char label; //图结点的值
Edge firstArc; //邻接的第一条弧
private Edge p; //工作指针
private boolean pt; //用pt来指示是否是第一次调用hasNextArc和nextArc
public boolean hasNextArc(){
if(pt==false){ //第一次调用那么 p=firstArc
p=firstArc;
pt=true;
}
if(p!=null)
return true;
else {
pt=false;
return false;
}
}
public Edge nextArc(){
Edge re=p;
p=p.nextArc;
return re;
}
}
注意在hasNextArc()中的else里pt最终赋值为false。进入这个else的时候,当前结点的弧已经完全遍历了,将pt赋值为false方便下次调用hasNextArc()时候依然从头开始遍历。