jules0707

Weighted Quick Union Path Compression UF

Nov 6th, 2017
202
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 7.26 KB | None | 0 0
  1. package edu.princeton.cs.algs4;
  2.  
  3. /******************************************************************************
  4.  * Compilation: javac WeightedQuickUnionPathCompressionUF.java Execution:
  5.  * java WeightedQuickUnionPathCompressionUF < input.txt Dependencies:
  6.  * StdIn.java StdOut.java Data files:
  7.  * https://algs4.cs.princeton.edu/15uf/tinyUF.txt
  8.  * https://algs4.cs.princeton.edu/15uf/mediumUF.txt
  9.  * https://algs4.cs.princeton.edu/15uf/largeUF.txt
  10.  *
  11.  * Weighted quick-union with path compression.
  12.  *
  13.  ******************************************************************************/
  14.  
  15. /**
  16.  * The {@code WeightedQuickUnionPathCompressionUF} class represents a union–find
  17.  * data structure. It supports the <em>union</em> and <em>find</em> operations,
  18.  * along with methods for determining whether two sites are in the same
  19.  * component and the total number of components.
  20.  * <p>
  21.  * This implementation uses weighted quick union (by size) with full path
  22.  * compression. Initializing a data structure with <em>n</em> sites takes linear
  23.  * time. Afterwards, <em>union</em>, <em>find</em>, and <em>connected</em> take
  24.  * logarithmic time (in the worst case) and <em>count</em> takes constant time.
  25.  * Moreover, the amortized time per <em>union</em>, <em>find</em>, and
  26.  * <em>connected</em> operation has inverse Ackermann complexity.
  27.  * <p>
  28.  * For additional documentation, see
  29.  * <a href="https://algs4.cs.princeton.edu/15uf">Section 1.5</a> of
  30.  * <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
  31.  *
  32.  * @author Robert Sedgewick
  33.  * @author Kevin Wayne
  34.  */
  35. public class WeightedQuickUnionPathCompressionUF {
  36.     private int[] parent; // parent[i] = parent of i
  37.     private int[] size; // size[i] = number of sites in tree rooted at i
  38.                         // Note: not necessarily correct if i is not a root
  39.                         // node
  40.     private int count; // number of components
  41.  
  42.     /**
  43.      * Initializes an empty union–find data structure with {@code n} sites
  44.      * {@code 0} through {@code n-1}. Each site is initially in its own
  45.      * component.
  46.      *
  47.      * @param n
  48.      *            the number of sites
  49.      * @throws IllegalArgumentException
  50.      *             if {@code n < 0}
  51.      */
  52.     public WeightedQuickUnionPathCompressionUF(int n) {
  53.         count = n;
  54.         parent = new int[n];
  55.         size = new int[n];
  56.         for (int i = 0; i < n; i++) {
  57.             parent[i] = i;
  58.             size[i] = 1;
  59.         }
  60.     }
  61.  
  62.     /**
  63.      * Returns the number of components.
  64.      *
  65.      * @return the number of components (between {@code 1} and {@code n})
  66.      */
  67.     public int count() {
  68.         return count;
  69.     }
  70.  
  71.     /**
  72.      * Returns the component identifier for the component containing site
  73.      * {@code p}.
  74.      *
  75.      * @param p
  76.      *            the integer representing one site
  77.      * @return the component identifier for the component containing site
  78.      *         {@code p}
  79.      * @throws IllegalArgumentException
  80.      *             unless {@code 0 <= p < n}
  81.      */
  82.     public int find(int p) {
  83.         validate(p);
  84.         int root = p;
  85.         // we find the root, then we have two choices almost as fast
  86.         while (root != parent[root])
  87.             root = parent[root];
  88.  
  89.         // option 1: with grand parent path compression
  90.         while (p != root) {
  91.             int newp = parent[p];
  92.             parent[p] = root;
  93.             p = newp;
  94.         }
  95.  
  96.        // option 2: with full path compression
  97.        // in practice linear time m log n
  98.         while (p != root) {
  99.             int newp = parent[p];
  100.             parent[p] = root;
  101.             p = newp;
  102.         }
  103.         return root;
  104.     }
  105.  
  106.     /**
  107.      * Returns true if the the two sites are in the same component.
  108.      *
  109.      * @param p
  110.      *            the integer representing one site
  111.      * @param q
  112.      *            the integer representing the other site
  113.      * @return {@code true} if the two sites {@code p} and {@code q} are in the
  114.      *         same component; {@code false} otherwise
  115.      * @throws IllegalArgumentException
  116.      *             unless both {@code 0 <= p < n} and {@code 0 <= q < n}
  117.      */
  118.     public boolean connected(int p, int q) {
  119.         return find(p) == find(q);
  120.     }
  121.  
  122.     // validate that p is a valid index
  123.     private void validate(int p) {
  124.         int n = parent.length;
  125.         if (p < 0 || p >= n) {
  126.             throw new IllegalArgumentException(
  127.                     "index " + p + " is not between 0 and " + (n - 1));
  128.         }
  129.     }
  130.  
  131.     /**
  132.      * Merges the component containing site {@code p} with the the component
  133.      * containing site {@code q}.
  134.      *
  135.      * @param p
  136.      *            the integer representing one site
  137.      * @param q
  138.      *            the integer representing the other site
  139.      * @throws IllegalArgumentException
  140.      *             unless both {@code 0 <= p < n} and {@code 0 <= q < n}
  141.      */
  142.     public void union(int p, int q) {
  143.         int rootP = find(p);
  144.         int rootQ = find(q);
  145.         if (rootP == rootQ)
  146.             return;
  147.  
  148.         // make smaller root point to larger one
  149.         if (size[rootP] < size[rootQ]) {
  150.             parent[rootP] = rootQ;
  151.             size[rootQ] += size[rootP];
  152.         } else {
  153.             parent[rootQ] = rootP;
  154.             size[rootP] += size[rootQ];
  155.         }
  156.         count--;
  157.     }
  158.  
  159.     /**
  160.      * Reads in a sequence of pairs of integers (between 0 and n-1) from
  161.      * standard input, where each integer represents some site; if the sites are
  162.      * in different components, merge the two components and print the pair to
  163.      * standard output.
  164.      *
  165.      * @param args
  166.      *            the command-line arguments
  167.      */
  168.     public static void main(String[] args) {
  169.         int n = StdIn.readInt();
  170.         WeightedQuickUnionPathCompressionUF uf = new WeightedQuickUnionPathCompressionUF(
  171.                 n);
  172.         while (!StdIn.isEmpty()) {
  173.             int p = StdIn.readInt();
  174.             int q = StdIn.readInt();
  175.             if (uf.connected(p, q))
  176.                 continue;
  177.             uf.union(p, q);
  178.             StdOut.println(p + " " + q);
  179.         }
  180.         StdOut.println(uf.count() + " components");
  181.     }
  182.  
  183. }
  184.  
  185. /******************************************************************************
  186.  * Copyright 2002-2016, Robert Sedgewick and Kevin Wayne.
  187.  *
  188.  * This file is part of algs4.jar, which accompanies the textbook
  189.  *
  190.  * Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne, Addison-Wesley
  191.  * Professional, 2011, ISBN 0-321-57351-X. http://algs4.cs.princeton.edu
  192.  *
  193.  *
  194.  * algs4.jar is free software: you can redistribute it and/or modify it under
  195.  * the terms of the GNU General Public License as published by the Free Software
  196.  * Foundation, either version 3 of the License, or (at your option) any later
  197.  * version.
  198.  *
  199.  * algs4.jar is distributed in the hope that it will be useful, but WITHOUT ANY
  200.  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  201.  * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  202.  *
  203.  * You should have received a copy of the GNU General Public License along with
  204.  * algs4.jar. If not, see http://www.gnu.org/licenses.
  205.  ******************************************************************************/
Add Comment
Please, Sign In to add comment