早就说要开始系统的学算法了,可总是被这个事那个事所拖累,从今天开始,认真拿着《算法》跟着coursera上的课程学算法。
算法的设计总是由API的设计开始,先将需要解决的问题抽象化,对需要的功能写出相应的API,然后在考虑解决这个问题用什么数据结构最好,最后再开始实现各个API。
关于Union_Find问题,判断两个对象之间是否联通的一个抽象的想法便是将union的对象放进同一个集合中,查询时若两个对象在一个集合中就是有路线可以联通。相应的我们就可以用数组来模拟对象所在集合,并且我们需要union,connected这两个简单的操作,还有一个构造函数读入对象。
<1>Quick-connect算法:很明显,算法的核心问题就是如何实现union和connected这两个API。快查算法的实现非常简单,初始化时给所有对象一个id,表示每个对象处于不同的集合。进行union操作时,如果id不同,就遍历整个数组将所有和其中一个对象id相同的对象的id都改成后一个对象的id。查询操作就会非常方便,只要比较两者id是否相同,即可判断是否联通。
<2>Quick-union算法:第一种实现方法最大的问题便是每次union都要遍历数组,效率太低,Quick-union算法是模拟树的实现,union时只要将根节点相连,整个集合就合二为一了。但这种问题带来了另外一个问题,那就是可能存在“瘦高”的树,那么去查询这种树的根节点将会非常耗费时间。
<3>Quick-union improvements:不过,我们完全可以优化上一算法来解决这个问题。增加一个数组变量来记录每个树的大小,当union时,总是将小树连接在大树的根节点下。这个看似小小的操作将大大提升运算效率,在大数据量下,会将平方级的运算提升至对数级。