zoukankan      html  css  js  c++  java
  • 再议并查集

    再议并查集

             上文《并查集》中,我们讨论了并查集的数据结构和基本操作,以及给出了个基本实现。我们指出理解并运用好并查集重点在于理解元素的表示、类别的表示、元素的索引,以及三者之间的关系。

             在实现中,我们指出Find的参数x是为data的索引(等价于father的索引),用索引表示实际的元素,并Find出其类别。这里我们补充一点:Find函数返回的是参数x对应的类别,这里的类别表示依然是用data的索引进行的表示,返回的索引(返回值)实质上是所述类别的祖先节点的索引。

             同样Union函数的两个参数实质是data的索引(等价于father的索引),但表示的是其对应的元素所述的类别。在Union中,int型的量有的时候是索引的意思,有的时候是类别的意思。

             以上我们是回顾了上文中关于并查集操作函数参数和返回值意义的讨论。这里,我们重点讨论一下并查集的三个数据结构,通过对着三个数据结构的理解,我们能够对并查集有更深的理解,同样有助于我们理解其操作函数。

             三个数据结构分别是:

             vector<int> data(NUM);

             vector<int> father(NUM);

             vector<int> nRank(NUM);

             分别对应于元素集合、类别信息、秩信息。我们首先分析一下这三个数据结构可以是什么类型的数据,然后根据分析,讨论并查集的操作函数参数类型以及返回值类型。

             元素集合

             元素集合的类型可以是任意的,因为元素可以是各种各样的类型,可以是int、double、string等等。我们不能对元素类型进行限制。

             类别信息

             结合我们的Find函数实现,father[father[father[…]]],可知father[]的值又作为father[]的索引,因为索引需要是整型的,所以father[]的值的类型应该也是整型的。所以类别信息应该是整型的,否则无法通过father树进行逐层查找祖先类别。假设类别信息时字符串类型的,那么father[]索引必须支持字符串,虽然map、set等支持字符串索引,但是,如果这样的话,Find函数的参数必须作为father[]的索引,也就是Find函数的参数也要是字符串类型,但是字符串类型的Find参数无法与元素集合中的元素相对应。即便元素类型也是字符类型的,Find函数是直接传递的元素值,如果father是map,first为元素值,second为类别名,这种也倒支持string的索引了,但是因为支持[]操作,所以要求必须是map,也就是元素集合中的元素必须互异。

             一般情况下,类别信息应该只能是整型的。如果实际的类别信息为字符串类型,可以建立一个整型数到字符串映射。

             秩信息

             由于father树中,节点的高度只能是整型的,从0开始。所以秩信息只能是整型的。其实,如果极端一点,只要支持<、==就符合秩信息类型的要求,比如string,秩信息可以使用string类型,但是这样就太古怪了。

             综上所述,元素集合可以是任意类型,类别信息和秩信息只能是整型的

             对于并查集的操作函数,Find的参数必须能够代表元素集合的某个元素,最直接的方法就是元素类型,但是如果元素类型为字符串型,因为类别信息为整型,所以不支持字符串类型。最简单和直接的方法就是使用元素的索引,这个索引同样是类别信息的索引。对于返回值来说,返回的是类别信息,所以也只能是整型。Union参数应该是两个类别,由于类别的类型为整型,所以两个参数都为整型。

             初始化

             最后,我们谈论一下初始化操作。初始化是对集合元素、类别信息、秩信息进行初始化。既然知道了三个数据结构的类型,那么就可以根据已知的信息对三个数据结构进行初始化。需要注意的是,这三个数据结构中的元素需要一一对应的,因为集合中的每个元素都有一个类别信息,同样也有一个秩信息。对于给定的元素,我们都是尽量能够快速的定位其类别信息和秩信息。利用元素的索引进行定位无疑是最好的方法。因为,利用索引进行定位简单高效,前提是三个数据结构都是用索引型结构表示的。

             根据前面的讨论,也可以利用元素的值进行定位,这就要求类别信息和秩信息必须能够支持元素的值进行查找操作。如果元素的值是字符串,那么类别信息和秩信息必须能够通过字符串找到该元素对应的类别信息和秩信息。实现的话,可以利用map来支撑,不能采用multimap,应为其不能返回准确的信息。利用map的前提是元素的值必须互异。

             所以,我们可以看出如果用元素的值作为查找类别信息和秩信息的手段(也就是Find的参数为元素的值类型),导致实现起来很繁琐,而且元素的值必须互异。另外father[]的值还要作为获取其类型的索引,也就说类型的值也要作为father的索引,那么类型的值也就是元素的值。所以,如果这种方式进行初始化的话,father必须初始化为元素的值。

             秩信息的初始化,其索引类型可以跟随类别信息的索引变换,但是其本身的类型只要支持<、==操作即可。

             总结

             通过分析并查集三个数据结构的类型,以及相互之间的关系,明白三个数据结构直接是怎么相互作用的。在这基础之上理解并查集操作函数的参数类型和返回值类型,以及为什么是这些类型。

  • 相关阅读:
    git hub 资料汇总
    java 实例化是调用了子类重写方法
    java接口示例
    cumber + selenium +java自动化测试
    解决selenium 启动ie浏览器报错:Unexpected error launching Internet Explorer. Protected Mode settings are not the same for all zones
    springmvc 数据回显功能
    springmvc管理资源开放
    springmvc 中controller与jsp传值
    springmvc注解事例
    springmvc
  • 原文地址:https://www.cnblogs.com/unixfy/p/3364102.html
Copyright © 2011-2022 走看看