Algs4 - Java Basics and Union Find, Java基础与并查集

Java Basics and Union-Find

Basics

  1. Java basics Data types; Abstract data types; Application programming interface (API); The following list contains some points need to pay attention.

    • Interface inheritance: subtyping:

    • comparison: java.lang.Comparable: compareTo(); java.util.Comparator: compare();

    • iteration: java.lang.Iterable: iterator(); java.util.Iterator: hasNext(), next(), remove()

    • Implementation inheritance: subclassing:

    • Class getClass() what class is this object?

    • String toString() string representation of this object.

    • boolean equals(Object that) is the object equal to that?

    • int hashCode() hash code for this object.

    • Equality

    • If we test equality with (a == b) where a and b are reference variables of the same type, we are testing whether they have the same identity: whether the references are equal. Typical clients would rather be able to test whether the data-type values (object state) are the same. Every Java type inherits the method equals() from Object. Java provides natural implementations both for standard types such as Integer, Double, and String and for more complicated types such as java.io.File and java.net.URL. When we define our own data types we need to override equals(). Java’s convention is that equals() must be an equivalence relation:

      Reflexive: x.equals(x) is true.

      Symmetric: x.equals(y) is true if and only if y.equals(x) is true.

      Transitive: if x.equals(y) and y.equals(z) are true, then so is x.equals(z).

      In addition, it must take an Object as argument and satisfy the following properties.

      Consistent: multiple invocations of x.equals(y) consistently return the same value, provided neither object is modified.

      Not null: x.equals(null) returns false.

      Adhering to these Java conventions can be tricky, as illustrated for Date.java and Transaction.java.

      /**
      * Compares this date to the specified date.
      *
      * @param  other the other date
      * @return {@code true} if this date equals {@code other}; {@code false} otherwise
      */
      @Override
      public boolean equals(Object other) {
        if (other == this) return true;
        if (other == null) return false;
        if (other.getClass() != this.getClass()) return false;
        Date that = (Date) other;
        return (this.month == that.month) && (this.day == that.day) && (this.year == that.year);
      }
      
    • Wrapper types

      boolean -> Boolean, byte -> Byte, char -> Character, double -> Double, int -> Integer, long, short, float…

    • Immutability:
      Immutable objects: String is immutable, Primitive wrappers (Integer, Long, Short, Double, Float, Character, Byte, Boolean) are also all immutable. Reference types cannot be made immutable just by using the final keyword. final only prevents reassignment.
      Difference between final and immutable

  2. Bags, Queues, and Stacks

    • Resizing array implementation
    • Linked Lists implementation.
  3. Analysis of algorithms

    • Big O notation, Big Theta notation …

Case study: Union-Find

  • array implementation, Quick Find (QF) QuickFindUF.java

    maintains the invariant that p and q are connected if and only if id[p] is equal to id[q]. In other words, all sites in a component must have the same value in id[].

    Union: O(N). Find: O(1). Construct: O(N). Takes N^2 array access to process sequence of N union commands on N objects.

    /* 
    main function of QuickFindUF.java
    */
    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 find(int p) {
        return id[p];
    }
    public boolean connected(int p, int q) {
        return id[p] == id[q];
    }
    public void union(int p, int q) {
        int pID = id[p];
        int qID = id[q];
        if (pID == qID) return;
        for (int i = 1; i < n; i++) {
            if (id[i] = pID) id[i] = qID;
        }
        count--;
    }
    }
    
  • Quick-union. QuickUnionUF.java

    private int[] parent;
    public QuickUnionUF(int n) {
      count = n;
      parent = new int[n];
      for (int i = 0; i < n; i++) {
          parent[i] = i;
      }
    }
    public int find(int p) {
      while (p != parent[p]) 
          p = parent[p];
      return p;
    }
    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--;
    }
    
  • Weighted Quick Union. Rather than arbitrarily connecting the second tree to the first for union() in the quick-union algorithm, we keep track of the size of each tree and always connect the smaller tree to the larger. Program WeightedQuickUnionUF.java implements this approach.
    Find and Union both O(lgN)

    /*
    find and connected the same with QuickUnionUF.java
    An extra array size[], size[i] was used to identify the number of elements in subtree rooted at i
    */
    public WeightedQuickUnionUF() {
      count = n;
      parent = new int[n];
      size = new int[n];
      for (int i = 0; i < n; i++) {
          parent[i] = i;
          size[i] = 1;   // initial size is 1.
      }
    }
    public void union(int p, int q) {
      int rootP = find(p);
      int rootQ = find(q);
      if (rootP == rootQ) return;
      // make smaller root point to larger root
      if (size(rootP) < size(rootQ)) {
         parent[rootP] = rootQ;
         size[rootQ] += size[rootP];
      }
      else {
          parent[rootQ] = rootP;
          size[rootP] += size[rootQ];
      }
      count--;
    }
    
  • Weighted quick-union with path compression

    /*
    Simple one-pass variant: Make every other node in path point to its grandparent (thereby halving path length)  
    Keep tree almost completely flat in practice.
    */
    private int root(int i) {
      while (i != id[i]) {
          id[i] = id[id[i]];
          i = id[i];
      }
      return i;
    }
    

Union-Find Exercise: Percolation

Programming assignment Specification
My submission

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值