在这部分内容里,我们用HashTable取代AVLTree以进一步提高系统的检索效率。毕竟我们不需要AVLTree的排序功能。另外,从纯粹的理论上来说,AVLTree的算法复杂度至少是O(Log2(x))级别,而HashTable则接近于O(C)级别。
一、 使用HashTable
在华容道程序中,要搜索以前出现过的布局,及时消除重复布局。早最初的设计中,我使用AVLTree来达到这个目的。AVLTree是基于比较运算来进行搜索的,其算法的复杂度为O(Log2(n))级别,也是基于比较的搜索算法所能达到的最高效率。要想继续提高搜索效率,就得考虑使用非基于比较的运算。Hash算法就是一个非常值得推荐的算法,它理论的平均时间复杂度是1。
关于Hash算法,推荐读一读Wayfarer翻译的《考察数据结构——第二部分:队列、堆栈和哈希表[译] 》。我在这里就不再重复。在华容道程序中,我选择使用链地址法实现HashTable(我没有使用微软提供的HashTable)。尽管从理论上讲,二次探测法的效率应当比链地址法效率高,但在华容道程序测试中,链地址效率要高很多。另外,HashCode的计算方法采用了折叠累加的方法,通过对布局Int64表示进行折叠累加得到HashCode。
链地址法如下图所示:
链地址法的数据插入和删除比较简单,如果HashCode的计算是高效的,那么在同一个位置的键值就很少,搜索长度也会很短,而且可以很节省空间。我的Hash算法经验证,一个HashCode下最多出现10个节点,平均为3个节点左右。
HashCode的计算如下:
![](https://www2.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
完整的HashTable代码如下:
![](https://www2.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
二、 对解题效率的提升
经过修改后,程序的执行效率进一步提升。原来程序中的第四个布局的解题时间从上次优化的1秒缩短到了0.8秒。虽然这个运算时间已经很短了,但是我们还能不能再榨出点时间来呢?当然可以!
"数据结构+算法=程序",在前面的优化里,我重新对数据结构进行了调整:用Int64表示布局、用HashTable检索重复。但是数据结构的改变往往要求算法对应发生变化,这样程序才能显得协调。在《华容到与数据结构 (续 3)》里,将重新对棋盘表示以及走法进行设计,调整后的程序运行时间会缩短到0.6秒。
在《华容到与数据结构 (续 4)》中,我会继续提高执行效率,推出"超级优化版"(如果效率还能提高就叫"超超级优化版"、"超超超级优化版"),程序解题时间会缩短至0.42秒。如果不算屏幕结果显示的时间的化,仅需0.34秒。