Quick-find
package com.qiusongde; import edu.princeton.cs.algs4.StdDraw; import edu.princeton.cs.algs4.StdIn; import edu.princeton.cs.algs4.StdOut; public class UFQuickFind { private int[] id;//access to component id (site indexed) private int count;//number of components private static int cost = 0;//for plot public UFQuickFind(int n) { //initialize count and id count = n; id = new int[n]; for(int i = 0; i < n; i++) { id[i] = i; } } public int count() { return count; } public boolean connected(int p, int q) { return find(p) == find(q); } public int find(int p) { cost++;//for plot return id[p]; } public void union(int p, int q) { int pID = find(p); int qID = find(q); //do nothing if p and q are already //in the same component if(pID == qID) return; //rename p's component to q's name for(int i = 0; i < id.length; i++) { if(id[i] == pID) { id[i] = qID; cost++;//for plot } cost++;//for plot } count--; } @Override public String toString() { String s = ""; for(int i = 0; i < id.length; i++) { s += id[i] + " "; } s += " " + count + " components"; return s; } //for plot private static void initStdDraw() { StdDraw.setXscale(0, 900); StdDraw.setYscale(0, 1300); StdDraw.setPenRadius(0.002); StdDraw.textLeft(1, 625, "625"); } //for plot private static void plot(int i, int cost, int totalcost) { double average = (totalcost * 1.0) / i; StdDraw.setPenColor(StdDraw.BLACK); StdDraw.point(i, cost); StdDraw.setPenColor(StdDraw.RED); StdDraw.point(i, average); } public static void main(String[] args) { //initialize N components int N = StdIn.readInt(); UFQuickFind uf = new UFQuickFind(N); // StdOut.println(uf); //total cost for plot int totalcost = 0; int i = 0;//ith connection processed initStdDraw(); while(!StdIn.isEmpty()) { cost = 0;//initialize for every inputs pair, for plot int p = StdIn.readInt(); int q = StdIn.readInt(); if(uf.connected(p, q)) {//ignore if connected // StdOut.println(p + " " + q + " is connected"); totalcost += cost;//compute total cost, for plot i++; plot(i, cost, totalcost); continue; } uf.union(p, q);//connect p and q // StdOut.println(p + " " + q); // StdOut.println(uf); totalcost += cost;//compute total cost, for plot i++; plot(i,cost,totalcost); } } }
Quick-union
package com.qiusongde; import edu.princeton.cs.algs4.StdDraw; import edu.princeton.cs.algs4.StdIn; import edu.princeton.cs.algs4.StdOut; public class UFQuickUnion { private int[] id;//save the site's parent link(site indexed) private int count;//number of components private static int cost = 0;//for plot public UFQuickUnion(int n) { count = n; id = new int[n]; for(int i = 0; i < n; i++) id[i] = i; } public int count() { return count; } public boolean connected(int p, int q) { return find(p) == find(q); } public int find(int p) { //find root //id[p] save the parent of p while(p != id[p]) { p = id[p]; cost += 2;//for plot } cost++;//for plot return p; } public void union(int p, int q) { int pRoot = find(p);//find pRoot int qRoot = find(q);//find qRoot if(pRoot == qRoot) return; id[pRoot] = qRoot; cost++;//for plot count--; } @Override public String toString() { String s = ""; for(int i = 0; i < id.length; i++) { s += id[i] + " "; } s += " " + count + " components"; return s; } //for plot private static void initStdDraw() { StdDraw.setXscale(0, 900); StdDraw.setYscale(0, 1300); StdDraw.setPenRadius(0.002); StdDraw.textLeft(1, 650, "625"); } //for plot private static void plot(int i, int cost, int totalcost) { double average = (totalcost * 1.0) / i; StdDraw.setPenColor(StdDraw.BLACK); StdDraw.point(i, cost); StdDraw.setPenColor(StdDraw.RED); StdDraw.point(i, average); } public static void main(String[] args) { //initialize N components int N = StdIn.readInt(); UFQuickUnion uf = new UFQuickUnion(N); // StdOut.println(uf); //total cost for plot int totalcost = 0; int i = 0;//ith connection processed initStdDraw(); while(!StdIn.isEmpty()) { cost = 0;//initialize for every inputs pair, for plot int p = StdIn.readInt(); int q = StdIn.readInt(); if(uf.connected(p, q)) {//ignore if connected // StdOut.println(p + " " + q + " is connected"); totalcost += cost;//compute total cost, for plot i++; plot(i, cost, totalcost); continue; } uf.union(p, q);//connect p and q // StdOut.println(p + " " + q); // StdOut.println(uf); totalcost += cost;//compute total cost, for plot i++; plot(i, cost, totalcost); } } }
Weighted-quick union
package com.qiusongde; import edu.princeton.cs.algs4.StdDraw; import edu.princeton.cs.algs4.StdIn; import edu.princeton.cs.algs4.StdOut; public class UFWeightedQuickUnion { private int[] id;//parent link(site indexed) private int[] treesize;//size of component for roots(site indexed) private int count;//number of components private static int cost = 0;//for plot public UFWeightedQuickUnion(int N) { count = N; id = new int[N]; for(int i = 0; i < N; i++) id[i] = i; treesize = new int[N]; for(int i = 0; i < N; i++) treesize[i] = 1; } public int count() { return count; } public boolean connected(int p, int q) { return find(p) == find(q); } public int find(int p) { while(p != id[p]) { p = id[p]; cost += 2;//for plot } cost++;//for plot return p; } public void union(int p, int q) { int pRoot = find(p); int qRoot = find(q); if(pRoot == qRoot) return; //make smaller root point to larger one if(treesize[pRoot] < treesize[qRoot]) { id[pRoot] = qRoot; treesize[qRoot] += treesize[pRoot]; cost += 5;//for plot } else { id[qRoot] = pRoot; treesize[pRoot] += treesize[qRoot]; cost += 5;//for plot } count--; } @Override public String toString() { String s = ""; for(int i = 0; i < id.length; i++) { s += id[i] + " "; } s += " "; for(int i = 0; i < treesize.length; i++) { s += treesize[i] + " "; } s += " " + count + " components"; return s; } //for plot private static void initStdDraw() { StdDraw.setXscale(0, 900); StdDraw.setYscale(0, 1300); StdDraw.setPenRadius(0.002); StdDraw.textLeft(1, 625, "625"); } //for plot private static void plot(int i, int cost, int totalcost) { double average = (totalcost * 1.0) / i; StdDraw.setPenColor(StdDraw.BLACK); StdDraw.point(i, cost); StdDraw.setPenColor(StdDraw.RED); StdDraw.point(i, average); } public static void main(String[] args) { //initialize N components int N = StdIn.readInt(); UFWeightedQuickUnion uf = new UFWeightedQuickUnion(N); // StdOut.println(uf); //total cost for plot int totalcost = 0; int i = 0;//ith connection processed initStdDraw(); while(!StdIn.isEmpty()) { cost = 0;//initialize for every inputs pair, for plot int p = StdIn.readInt(); int q = StdIn.readInt(); if(uf.connected(p, q)) {//ignore if connected // StdOut.println(p + " " + q + " is connected"); totalcost += cost;//compute total cost, for plot i++; plot(i, cost, totalcost); continue; } uf.union(p, q);//connect p and q // StdOut.println(p + " " + q); // StdOut.println(uf); totalcost += cost;//compute total cost, for plot i++; plot(i, cost, totalcost); } } }