这个星期要做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");
}
}
层层递进,第四中方法是最快的,所以我给老师检查的是第四种,都有注释。