迷宫生成算法–并查集
好书好书
在看《数据结构与算法分析》这本书的时候看到后面的一个关于并查集的有趣应用,是个生成迷宫的算法,看起来非常有趣,所以就实现了一下。顺便把几种走迷宫的算法都整了 进去。八卦一下,这本书的作者是Mark Weiss,这牛写了几本数据结构和算法的书,各种语言版本(C,C++,Java),原来是师出名门啊,在他的主页上一看,原来是Robert Sedgewick 的学生。Sedgewick更是师出名门,在Princeton跟高纳德神牛读的博士,也写了N本算法和数据结构的书。这两人写的书都还不错,对于初学者和中等水平来说很好,覆盖了一般的数据结构和算法,同时带有一定的理论分析还有特定的语言实现。
并查集
可能一般的大学教材上面没有说这个数据结构,这是个很有趣的东西。《算法导论》上面用这个来作为均摊分析的例子吧。在ACM/ICPC中这个数据结构经常出现,有可能是一个小题 (难点的就是要维护节点之间关系的那种),或者是有的图论算法中实现要用,比如实现Kruskar算法求最小生成树。
并查集本身比较简单,主要是用来操作元素集合,支持的操作有:
- UnionSets(int root1,int root2),用来合并两个根节点。
- FindSet(int x) ,用来查找x所属的根节点。 一并一查,所以叫作并查集。实现时候可以通过按秩合并(union by rank),和路径压缩(path compression)来增加效率,可以获得几乎与总操作数m成线性关系的运行时间。
int rank[MAXSIZE]; // 节点高度的上界 int parent[MAXSIZE]; // 根节点 void Init(void){ memset(rank, 0, sizeof(rank)); for(int i=0; i < MAXSIZE; ++i ) parent[i] = i; } int FindSet(int x){// 查找+递归的路径压缩 if( x != parent[x] ) parent[x] = FindSet(parent[x]); return parent[x]; } void UnionSet(int root1, int root2){ int x = FindSet(root1), y = FindSet(root2); if( x == y ) return ; if( rank[x] > rank[y] ) parent[y] = x; else{ parent[x] = y; if( rank[x] == rank[y] ) ++rank[y]; } }
迷宫的实现
上面那本书上的习题上给了提示,比如首先所有的墙都没有去掉,那么是一个一个的方格,每一个方格为并查集合的一个元素,已经连通的元素是在并查集的一个集合中,有相同的根节点。 随机的选择一个墙,在并查集中查询这两个元素是否已经连通,如果已经连通则另选一个墙,如果不连通,union两个节点的根节点,这样操作以后这两个方格已经连通。继续上面的操作, 直到入口和出口连通位置,那么这就形成了一个只有一条合法路径的迷宫,称为单迷宫。如下图所示。







七月 21st, 2010 at 3:41 下午
这个又是用OpenGL实现的?很酷
[回复]
七月 22nd, 2010 at 8:26 上午
嗯
[回复]
十月 23rd, 2010 at 4:03 下午
这个方法生成的迷宫好像不是标准迷宫呢
[回复]
moorekang 回复:
十月 24th, 2010 at 12:43 下午
标准的迷宫是怎么定义的?我也不清楚 呵呵
[回复]
十一月 15th, 2010 at 6:54 下午
汗,我也是通过Weiss那本书看到用并查集实现迷宫的。
[回复]
moorekang 回复:
十一月 15th, 2010 at 6:58 下午
哈哈 都差不多咯
[回复]
Tanky Woo 回复:
十一月 18th, 2010 at 4:42 下午
@moorekang,
哎,还准备在控制台下实现,不过似乎有点麻烦,还是和先前那个随机+深搜一样,得把墙和路都看成结点。
还是GUI下好啊。
[回复]
moorekang 回复:
十一月 18th, 2010 at 5:23 下午
我用的是glui,很好的一个框架 ,还跨平台的。
[回复]
Tanky Woo 回复:
十一月 18th, 2010 at 6:11 下午
我还是暂时把win api给学下。感觉这个是基础。
在CUI下编程多了人会厌倦的。。。
[回复]
C瓜哥 回复:
十二月 3rd, 2010 at 1:08 下午
@Tanky Woo,
引用“在GUI下编程多了人会厌倦的”
看来你不适合搞软件了,适合当算法设计师
[回复]
十二月 3rd, 2010 at 1:48 下午
似乎回复不了瓜哥。。。还是在这里写出来吧。
瓜哥,你看错了,我写的是CUI,不是GUI。。。
[回复]
moorekang 回复:
十二月 3rd, 2010 at 5:09 下午
@Tanky Woo, 哈哈 瓜哥GUI做的炫
[回复]