并查集(Union—find)算法实现简单的迷宫

           最近学到并查集(Union—find)算法,感觉很有意思,来做个学习笔记。假设在互联网中有两台计算机需要互相通信,那么该怎么确定它们之间是否已经连接起来以确定是否需要架设新的线路连接这两台计算机。这就是动态连通性问题。动态连通性问题在日常生活中十分常见,比如上文所说的通信网络中的连通性问题,比如物理化学中的渗流问题。通过并查集这种数据结构及union-find算法可以解决动态连通性问题。

并查集:(union-find sets)是一种简单的用途广泛的集合并查集是若干个不相交集合,能够实现较快的合并和判断元素所在集合的操作,应用很多。一般采取树形结构来存储并查集,并利用一个rank数组来存储集合的深度下界,在查找操作时进行路径压缩使后续的查找操作加速。这样优化实现的并查集,空间复杂度为O(N),建立一个集合的时间复杂度为O(1)N次合并M查找的时间复杂度为O(M Alpha(N)),这里AlphaAckerman函数的某个反函数,在很大的范围内(人类目前观测到的宇宙范围估算有1080次方个原子,这小于前面所说的范围)这个函数的值可以看成是不大于4的,所以并查集的操作可以看作是线性的。

问题描述:
给定一个n个序列的对象,有两种操作:
     -Union command:连接两个对象;
     -Find/connected query:两个对象是否连接(有路径)
算法实现:
1.用一个数组保存着每个对象所在的connected component,这种方式可以快速进行FIND,但是在union操作时需要遍历整个对象数组
2.利用树的观点,在数组中保存每个对象节点的parent,这个每个connected component就是一棵树,这种方式union很高效,只需要更新相应节点的parent即可,但是在find的时候可能就会遍历整个树,特别是当一棵树比较高的时候。
3.在上述2中实现union(p,q)的时候,我们用一种特定的方式将p所在的树的置为q所在树的孩子,没有考虑到树的大小,就会导致严重失衡的情况。Weighted quick-union 引入一个新的数组来保存每棵树的尺寸,总是将小树链入到大树下,实现相对的平衡。
4.利用path compression进一步对上述算法进行优化,在每一次root操作的时候,不单单只是追溯查询一个节点的根,而是动态的将其根节点往上推进。从而使得component tree 越来越平坦化。如下要查询节点6的根节点,在查询的最后会更新6直接指向根节点。
并查集(Union—find)算法实现简单的迷宫_第1张图片

接下来会把3,1分别指针指向root:

并查集(Union—find)算法实现简单的迷宫_第2张图片

       生成迷宫的大概思路是从各处的墙壁开始(入口和出口除外),不断随机选择一面墙,如果被墙分隔的单元不连通,就拆掉该墙,重复此过程直到开始单元和终止单元连通。入口位于左上角,出口位于右下角。

   如图所示:

并查集(Union—find)算法实现简单的迷宫_第3张图片

参考博客:

http://blog.csdn.net/vonzhoufz/article/details/36202227

http://liyuan462.iteye.com/blog/1152630

http://blog.csdn.net/fisher_jiang/article/details/1116918

http://www.tuicool.com/articles/7RBFne7

你可能感兴趣的:(并查集(Union—find)算法实现简单的迷宫)