package edu.princeton.cs.algs4.ch15;
import edu.princeton.cs.introcs.*;
/****************************************************************************
* Compilation: javac QuickFindUF.java
* Execution: java QuickFindUF < input.txt
* Dependencies: StdIn.java StdOut.java
*
* Quick-find algorithm.
*
****************************************************************************/
/**
* The <tt>QuickFindUF</tt> class represents a union-find data structure.
* It supports the <em>union</em> and <em>find</em> operations, along with
* methods for determinig whether two objects are in the same component
* and the total number of components.
* <p>
* This implementation uses quick find.
* Initializing a data structure with <em>N</em> objects takes linear time.
* Afterwards, <em>find</em>, <em>connected</em>, and <em>count</em>
* takes constant time but <em>union</em> takes linear time.
* <p>
* For additional documentation, see <a href="http://algs4.cs.princeton.edu/15uf">Section 1.5</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class QuickFindUF {
private int[] id; // id[i] = component identifier of i
private int count; // number of components
/**
* Initializes an empty union-find data structure with N isolated components 0 through N-1.
* @throws java.lang.IllegalArgumentException if N < 0
* @param N the number of objects
*/
public QuickFindUF(int N) {
count = N;
id = new int[N];
for (int i = 0; i < N; i++)
id[i] = i;
}
/**
* Returns the number of components.
* @return the number of components (between 1 and N)
*/
public int count() {
return count;
}
/**
* Returns the component identifier for the component containing site <tt>p</tt>.
* @param p the integer representing one site
* @return the component identifier for the component containing site <tt>p</tt>
* @throws java.lang.IndexOutOfBoundsException unless 0 <= p < N
*/
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 IndexOutOfBoundsException("index " + p + " is not between 0 and " + N);
}
}
/**
* Are the two sites <tt>p</tt> and <tt>q/tt> in the same component?
* @param p the integer representing one site
* @param q the integer representing the other site
* @return <tt>true</tt> if the two sites <tt>p</tt> and <tt>q</tt> are in
* the same component, and <tt>false</tt> otherwise
* @throws java.lang.IndexOutOfBoundsException unless both 0 <= p < N and 0 <= q < N
*/
public boolean connected(int p, int q) {
validate(p);
validate(q);
return id[p] == id[q];
}
/**
* Merges the component containing site<tt>p</tt> with the component
* containing site <tt>q</tt>.
* @param p the integer representing one site
* @param q the integer representing the other site
* @throws java.lang.IndexOutOfBoundsException unless both 0 <= p < N and 0 <= q < N
*/
public void union(int p, int q) {
if (connected(p, q)) return;
int pid = id[p];
for (int i = 0; i < id.length; i++)
if (id[i] == pid) id[i] = id[q];
count--;
}
/**
* Reads in a sequence of pairs of integers (between 0 and N-1) from standard input,
* where each integer represents some object;
* if the objects are in different components, merge the two components
* and print the pair to standard output.
*/
public static void main(String[] args) {
int N = StdIn.readInt();
QuickFindUF uf = new QuickFindUF(N);
while (!StdIn.isEmpty()) {
int p = StdIn.readInt();
int q = StdIn.readInt();
if (uf.connected(p, q)) continue;
uf.union(p, q);
StdOut.println(p + " " + q);
}
StdOut.println(uf.count() + " components");
}
}
/*************************************************************************
* Copyright 2002-2012, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4-package.jar, which accompanies the textbook
*
* Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
* Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
* http://algs4.cs.princeton.edu
*
*
* algs4-package.jar is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* algs4-package.jar is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with algs4-package.jar. If not, see http://www.gnu.org/licenses.
*************************************************************************/