最近在《算法》书中看到动态连通问题,今天给出其实现的代码。
接口
package com.chapter1;
public interface UnionFind {
int getCount();
boolean isConnected(int p,int q);
int find(int p);
void union(int p,int q);
}
抽象类
package com.chapter1;
public abstract class AbstractUnionFind implements UnionFind {
protected int[] ids;//分量id
protected int count;//分量数量
public AbstractUnionFind(int n){
count = n;
ids = new int[n];
for(int i=0;i<n;i++){
ids[i] = i;
}
}
public int getCount() {
return count;
}
public boolean isConnected(int p, int q) {
return find(p)==find(q);
}
public void printlnDetail(){
for(int i=0;i<ids.length;i++){
System.out.println(ids[i]);
}
}
}
Quick-find实现
package com.chapter1;
public class UnionQuickFind extends AbstractUnionFind{
public UnionQuickFind(int n){
super(n);
}
public int find(int p){
return ids[p];
}
public void union(int p,int q){
int idP = find(p);
int idQ = find(q);
if(idP == idQ) {
return;
}
for(int i=0;i<ids.length;i++){
if(ids[i]== idP){
ids[i] = idQ;
}
}
count--;
}
}
quick-union版本
package com.chapter1;
public class QuickUnionFind extends AbstractUnionFind{
public QuickUnionFind(int n){
super(n);
}
public int find(int p) {
while(p!=ids[p]){
p = ids[p];
}
return p;
}
public void union(int p, int q) {
int idP = find(p);
int idQ = find(q);
if(idP == idQ) {
return;
}
ids[idP] = idQ;
count--;
}
}
压缩的quick-union版本
package com.chapter1;
public class CompressQuickUnionFind extends QuickUnionFind {
public CompressQuickUnionFind(int n) {
super(n);
}
public int find(int p) {
int cur = p,next;
while(p != ids[p]){
p = ids[p];
}
while(ids[cur] != p) {
next = ids[cur];
ids[cur] = p;
cur = next;
}
return p;
}
}
带权重的quick-union
package com.chapter1;
public class WeightedQuickUnionFind extends QuickUnionFind {
private int[] sz;
WeightedQuickUnionFind(int n){
super(n);
sz = new int[n];
for(int i=0;i<n;i++){
sz[i] = 1;
}
}
@Override
public void union(int p,int q){
int idP = find(p);
int idQ = find(q);
if(idP == idQ) return;
if(sz[idP] < sz[idQ]){
ids[idP] = idQ;
sz[idQ] += sz[idP];
}else{
ids[idQ] = idP;
sz[idP] += sz[idQ];
}
count--;
}
}
压缩并带权重的quick-union
package com.chapter1;
public class CompressWeightedQuickUnionFind extends WeightedQuickUnionFind{
CompressWeightedQuickUnionFind(int n){
super(n);
}
@Override
public int find(int p){
int cur = p,next;
while(p != ids[p]){
p = ids[p];
}
while(ids[cur] != p) {
next = ids[cur];
ids[cur] = p;
cur = next;
}
return p;
}
}