分享给大家:)
***
(0) [符号说明]
S: Set F: Set的Set(全部的Set)
X: element的集合
(1) 为了方便我们先把所有的Set标上编号,
也就是变成S_1, S_2, ..., S_|F| // O(|F|)
(2) 对于每个element,我们给他一个"setList",用来记录有包含他自己的set:
maxNum = 0; // 这是为了之后开表格用的,纪录拥有最多元素的Set大小
for ( all S in F ) {
S.eleNum = 0; // 计算每个Set的Size
for ( all ele in S ) {
ele.chosen = false; // flag for 每个element只需被抓到一次
ele.setList.add( S );
S.eleNum++;
}
if ( S.eleNum > max )
max = S.eleNum;
} // O(sigma_S_in_F |S|)
(3) 建出一个有max+1格的bucket的list,其bucket对应的容量大小分别是0~max
接着再把每个Set依照其eleNum放到对应的bucket去:
for ( all S in F ) { // O(|F|)
bucket[S.eleNum].add( S );
S.pos = bucket[S.eleNum].size() - 1; // 纪录位置,之后remove可以const
}
(4) 从bucket容量最大的一路做到最小的,每做一个相对于选取一个Set
当一个element被选到时,我们就可以将其其他的Set的size-1,
并且移动到比较小的篮子里:
for ( k = max downto 1 ) { // O(|X|)
if ( bucket[k].size() == 0 )
continue;
for ( all S in bucket[k] ) { // O(|F|)
for ( all e in S ) {
if ( e.chosen == true )
continue;
for ( all E in e.setList ) {
oriSize = E.eleNum;
E.eleNum