-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
98 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
/* ***************************************************************************** | ||
* Name: Alan Turing | ||
* Coursera User ID: 123456 | ||
* Last modified: 1/1/2019 | ||
**************************************************************************** */ | ||
//this Assignment input data start 1~n | ||
import edu.princeton.cs.algs4.WeightedQuickUnionUF; | ||
|
||
public class Percolation { | ||
private int size; | ||
private boolean[][] grid; | ||
private WeightedQuickUnionUF uf; // for percolates() | ||
private WeightedQuickUnionUF backwashEliminateUF; | ||
private int treeSize; // size of the uf tree | ||
private int openBlockCount; | ||
|
||
// creates n-by-n grid, with all sites initially blocked | ||
// 0 = blocked 1 = open 2 = full | ||
public Percolation(int n) { | ||
size = n; | ||
treeSize = n*n+2; | ||
openBlockCount = 0; | ||
uf = new WeightedQuickUnionUF(treeSize); // add 2 nodes top and bottom | ||
backwashEliminateUF = new WeightedQuickUnionUF(treeSize - 1); // additional 1 node at top | ||
grid = new boolean[size][size]; | ||
|
||
for (int node = 0; node < n; node++) { | ||
uf.union(0, node+1); | ||
uf.union(treeSize - 1, treeSize - 2 - node); // treeSize-1 is the bottom, | ||
// start union from treeSize -2 | ||
backwashEliminateUF.union(0, node + 1); // union top node to top row | ||
} | ||
} | ||
|
||
// opens the site (row, col) if it is not open already | ||
public void open(int row, int col) { | ||
validateIndex(row, col); | ||
if(isOpen(row,col)) { | ||
return; | ||
} | ||
else { | ||
grid[row - 1][col - 1] = true; | ||
int treeIndex = xyTo1D(row, col); | ||
openBlockCount++; | ||
if (row > 1 && isOpen(row - 1, col)) { | ||
uf.union(xyTo1D(row - 1, col), treeIndex); | ||
backwashEliminateUF.union(xyTo1D(row - 1, col), treeIndex); | ||
} | ||
if (col > 1 && isOpen(row, col -1)) { | ||
uf.union(xyTo1D(row, col -1), treeIndex); | ||
backwashEliminateUF.union(xyTo1D(row, col -1), treeIndex); | ||
} | ||
if (row < size && isOpen(row + 1, col)) { | ||
uf.union(xyTo1D(row + 1, col), treeIndex); | ||
backwashEliminateUF.union(xyTo1D(row + 1, col), treeIndex); | ||
} | ||
if (col < size && isOpen(row, col + 1)) { | ||
uf.union(xyTo1D(row, col + 1), treeIndex); | ||
backwashEliminateUF.union(xyTo1D(row, col + 1), treeIndex); | ||
} | ||
} | ||
} | ||
|
||
// is the site (row, col) open? | ||
public boolean isOpen(int row, int col) { | ||
validateIndex(row, col); | ||
return grid[row - 1][col - 1]; | ||
} | ||
|
||
// is the site (row, col) full? | ||
public boolean isFull(int row, int col) { | ||
validateIndex(row, col); | ||
return isOpen(row, col) && backwashEliminateUF.connected(xyTo1D(row, col), 0); | ||
} | ||
|
||
// returns the number of open sites | ||
public int numberOfOpenSites() { | ||
return openBlockCount; | ||
} | ||
|
||
private void validateIndex(int i, int j) { | ||
if (i < 1 || i > size || j < 1 || j > size) | ||
throw new java.lang.IndexOutOfBoundsException(); | ||
} | ||
|
||
// does the system percolate? | ||
public boolean percolates() { | ||
if (size == 1) | ||
return isOpen(1, 1); // corner case gridSz = 1 | ||
return uf.connected(0, treeSize-1); | ||
} | ||
|
||
private int xyTo1D(int x, int y) { | ||
int oneD = (x - 1) * size + (y - 1) + 1; // + 1 from col(y) because of +1 node on top | ||
return oneD; | ||
} | ||
|
||
} |