union find算法

这个星期要做Union-find算法的作业,一直在想怎么引进.txt文件,同学找到一种方法:

1.首先把.txt文件保存到同一个包(不同的包也可以,但要用import导包);


2.选择Run下面的run  configuration,然后点击Common,会出现如下界面

3.选择File,点击Workspace,就会出现如下界面,选择你需要导入的文件,ok,然后点击apply,运行之后就会出结果。

以上的方法有一些eplise是没有这种方法的,但是不急还有另一种方法,因为老师检查的时候,要比较几个不同算法的快慢,所以我三种的都写了。


1.UF最原始的,但是也是时间最长的。

package algorithm;

import java.io.File;
import java.util.Scanner;

public class UF {

private int[] parent; // parent[i] = parent of i
private byte[] rank; // rank[i] = rank of subtree rooted at i (never more than 31)
private int count; // number of components


public UF(int n) {
if (n < 0) throw new IllegalArgumentException();
count = n;
parent = new int[n];
rank = new byte[n];
for (int i = 0; i < n; i++) {
parent[i] = i;
rank[i] = 0;
}
}


public int find(int p) {
validate(p);
while (p != parent[p]) {
parent[p] = parent[parent[p]]; // path compression by halving
p = parent[p];
}
return p;
}


public int count() {
return count;
}


public boolean connected(int p, int q) {
return find(p) == find(q);
}


public void union(int p, int q) {
int rootP = find(p);
int rootQ = find(q);
if (rootP == rootQ) return;

// make root of smaller rank point to root of larger rank
if (rank[rootP] < rank[rootQ]) parent[rootP] = rootQ;
else if (rank[rootP] > rank[rootQ]) parent[rootQ] = rootP;
else {
parent[rootQ] = rootP;
rank[rootP]++;
}
count--;
}

// validate that p is a valid index
private void validate(int p) {
int n = parent.length;
if (p < 0 || p >= n) {
throw new IllegalArgumentException("index " + p + " is not between 0 and " + (n-1));
}
}


public static void main(String[] args) throws Exception {

// 数据从外部文件读入,“data.txt”放在项目的根目录下
Scanner input = new Scanner(new File("tinyUF.txt"));
//tinyUF
//mediumUF
//largeUF
int n = input.nextInt();
WeightedQuickUnionUF uf = new WeightedQuickUnionUF(n);
StdOut.println(n);
while (input.hasNext()) {
int p = input.nextInt();
int q = input.nextInt();
if (uf.connected(p, q)) continue;
uf.union(p, q);
StdOut.println(p + " " + q);
}
StdOut.println(uf.count() + " components");
}

}


2.QuickFindUF
package algorithm;

import java.io.File;
import java.util.Scanner;

 

public class QuickFindUF {
    private int[] id;    // id[i] = component identifier of i
    private int count;   // number of components

   
    public QuickFindUF(int n) {
        count = n;
        id = new int[n];
        for (int i = 0; i < n; i++)
            id[i] = i;
    }
 
    public int count() {
        return count;
    }
  
   
    public int find(int p) {
        validate(p);
        return id[p];
    }

    // validate that p is a valid index
    private void validate(int p) {
        int n = id.length;
        if (p < 0 || p >= n) {
            throw new IllegalArgumentException("index " + p + " is not between 0 and " + (n-1));
        }
    }

   
    public boolean connected(int p, int q) {
        validate(p);
        validate(q);
        return id[p] == id[q];
    }
  
    
    public void union(int p, int q) {
        validate(p);
        validate(q);
        int pID = id[p];   // needed for correctness
        int qID = id[q];   // to reduce the number of array accesses

        // p and q are already in the same component
        if (pID == qID) return;

        for (int i = 0; i < id.length; i++)
            if (id[i] == pID) id[i] = qID;
        count--;
    }

 
 public static void main(String[] args) throws Exception {
    	
    	// 数据从外部文件读入,“data.txt”放在项目的根目录下
        Scanner input = new Scanner(new File("largeUF.txt"));
        //tinyUF
        //mediumUF
        //largeUF
        int n = input.nextInt();
        WeightedQuickUnionUF uf = new WeightedQuickUnionUF(n);
        StdOut.println(n);
        while (input.hasNext()) {
            int p = input.nextInt();
            int q = input.nextInt();
            if (uf.connected(p, q)) continue;
            uf.union(p, q);
            StdOut.println(p + " " + q);
        }
        StdOut.println(uf.count() + " components");
    }


}
3.QuickUnionUF

package algorithm;

import java.io.File;
import java.util.Scanner;

 
public class QuickUnionUF {
    private int[] parent;  // parent[i] = parent of i
    private int count;     // number of components

  
    public QuickUnionUF(int n) {
        parent = new int[n];
        count = n;
        for (int i = 0; i < n; i++) {
            parent[i] = i;
        }
    }

 
    public int count() {
        return count;
    }
  
 
    public int find(int p) {
        validate(p);
        while (p != parent[p])
            p = parent[p];
        return p;
    }

    // validate that p is a valid index
    private void validate(int p) {
        int n = parent.length;
        if (p < 0 || p >= n) {
            throw new IllegalArgumentException("index " + p + " is not between 0 and " + (n-1));
        }
    }

 
    public boolean connected(int p, int q) {
        return find(p) == find(q);
    }

  
 
    public void union(int p, int q) {
        int rootP = find(p);
        int rootQ = find(q);
        if (rootP == rootQ) return;
        parent[rootP] = rootQ; 
        count--;
    }

 
public static void main(String[] args) throws Exception {
    	
    	// 数据从外部文件读入,“data.txt”放在项目的根目录下
        Scanner input = new Scanner(new File("largeUF.txt"));
        //tinyUF
        //mediumUF
        //largeUF
        int n = input.nextInt();
        WeightedQuickUnionUF uf = new WeightedQuickUnionUF(n);
        StdOut.println(n);
        while (input.hasNext()) {
            int p = input.nextInt();
            int q = input.nextInt();
            if (uf.connected(p, q)) continue;
            uf.union(p, q);
            StdOut.println(p + " " + q);
        }
        StdOut.println(uf.count() + " components");
    }


}
4.WeightedQuickUnionUF
package algorithm;

import java.io.File;
import java.util.Scanner;

public class WeightedQuickUnionUF {
    private int[] parent;   // 父链接数组(由触点索引)
    private int[] size;     // 各个根节点所对应的分量的大小
    private int count;      // 连通分量的数量
 
    public WeightedQuickUnionUF(int n) { // 初始化时,N个点有N个分量
        count = n;
        parent = new int[n];
        size = new int[n];
        for (int i = 0; i < n; i++) {
            parent[i] = i;
            size[i] = 1;
        }
    }
 
    // 返回连通分量数
    public int count() {
        return count;
    }
  
    
    public int find(int p) {
        validate(p);
        //跟随链接找到根节点
        while (p != parent[p])
            p = parent[p];
        return p;
    }

    // 验证P是有效的索引
    private void validate(int p) {
        int n = parent.length;
        if (p < 0 || p >= n) {
            throw new IllegalArgumentException("index " + p + " is not between 0 and " + (n-1));  
        }
    }

    //如果p和q存在于同一个分量中则返回true
    public boolean connected(int p, int q) {
        return find(p) == find(q);
    }

    //在p和q之间添加一条连接
    public void union(int p, int q) {
    	//将p与q的根节点统一
        int rootP = find(p);
        int rootQ = find(q);
        if (rootP == rootQ) return;

        // 将小树的根节点连接到大树的根节点
        if (size[rootP] < size[rootQ]) {
            parent[rootP] = rootQ;
            size[rootQ] += size[rootP];
        }
        else {
            parent[rootQ] = rootP;
            size[rootP] += size[rootQ];
        }
        count--;
    }


  
    public static void main(String[] args) throws Exception {
    	
    	// 数据从外部文件读入,“data.txt”放在项目的根目录下
        Scanner input = new Scanner(new File("largeUF.txt"));
        //tinyUF.txt
        //mediumUF.txt
        //largeUF.txt
        int n = input.nextInt();
        WeightedQuickUnionUF uf = new WeightedQuickUnionUF(n);
        StdOut.println(n);
        while (input.hasNext()) {
            int p = input.nextInt();
            int q = input.nextInt();
            if (uf.connected(p, q)) continue;
            uf.union(p, q);
            StdOut.println(p + " " + q);
        }
        StdOut.println(uf.count() + " components");
    }

}
层层递进,第四中方法是最快的,所以我给老师检查的是第四种,都有注释。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值