十三、 TreeLinkedList的设计
在《华容道与数据结构 (2) 》中,设计了用于广度优先的树型链表。如下图:
链表是通过图中蓝颜色箭头链接起来的,而黑颜色箭头构成了树型结构。整个结构用来存储搜索结果,每一搜索步骤是一个层级,逐层深入直到找到结果。从图中可以看出,每个节点有两个指针,分别指向下一个节点与父节点。因此,在TreeLinkedList中定义节点类如下:
{
public ChessStep chessStep;
public TreeNode parentNode;
public TreeNode link;
}
chessStep是该节点的"负载",parentNode指向父节点,而link指向下一节点。在TreeLinkedList中有三个指针:
protected TreeNode current = null;
protected TreeNode end = null;
分别指向根节点,"当前"节点(所谓当前节点是指:所有新加入的节点的父节点都被设置为current指针指向的节点),链表尾节点。TreeLinkedList被初始化时,各指针均被清空,并将计数器清零。
{
root = null;
current = null;
end = null;
count = 0;
}
向树中插入节点的代码如下:
{
TreeNode newNode;
newNode = new TreeNode();
newNode.chessStep = newitem;
newNode.link = null;
newNode.parentNode = null;
if(root == null)
{
root = newNode;
current = newNode;
end = current;
}
else
{
newNode.parentNode = current;
end.link = newNode;
end = newNode;
end.link = newNode;
end = newNode;
}
count++;
}
可以看出,代码中新节点为newNode,如果根节点为空,则仅仅将root、current、end指针指向新节点。如果根节点不为空,那么将newNode节点的父节点指向current指针所指的节点,将end节点的下一个节点设置为newNode,然后将end指针指向newNode。于是新节点便被添加进来。除此之外,我们还需要一个方法,在合适的时候移动current指针:
{
if(current != null && current.link != null)
current = current.link;
}
现在,有了这些方法我们就可以构件TreeLinkedList结构了。如图:
要想构建上图所示树型结构,我们可以通过以下命令来实现:
TreeLinkedList t = new TreeLinkedList();
t.insertNode(s1);
t.insertNode(s2);
t.insertNode(s3);
t.MoveCurrentToNext();
t.insertNode(s4);
t.insertNode(s5);
t.MoveCurrentToNext();
t.insertNode(s6);
t.insertNode(s7);
t.insertNode(s8);
TreeLinkedList类中还有一个TraceResult,是用来通过堆栈结构追踪棋步的。比较简单,在这里就不再介绍了。
(下部分内容将介绍CircularLinkedList类。它是整个程序的核心。)