mirror of
https://github.com/TheAlgorithms/Java.git
synced 2025-07-26 05:59:22 +08:00
@ -22,8 +22,8 @@ public class GrahamScan {
|
||||
public GrahamScan(Point[] points) {
|
||||
|
||||
/*
|
||||
* pre-process the points by sorting them with respect to the bottom-most point, then we'll push the
|
||||
* first point in the array to be our first extreme point.
|
||||
* pre-process the points by sorting them with respect to the bottom-most point, then we'll
|
||||
* push the first point in the array to be our first extreme point.
|
||||
*/
|
||||
Arrays.sort(points);
|
||||
Arrays.sort(points, 1, points.length, points[0].polarOrder());
|
||||
@ -37,9 +37,9 @@ public class GrahamScan {
|
||||
if (indexPoint1 == points.length) return;
|
||||
|
||||
int indexPoint2;
|
||||
for (indexPoint2 = indexPoint1+1; indexPoint2 < points.length; indexPoint2++)
|
||||
for (indexPoint2 = indexPoint1 + 1; indexPoint2 < points.length; indexPoint2++)
|
||||
if (Point.orientation(points[0], points[indexPoint1], points[indexPoint2]) != 0) break;
|
||||
hull.push(points[indexPoint2-1]);
|
||||
hull.push(points[indexPoint2 - 1]);
|
||||
|
||||
// Now we simply add the point to the stack based on the orientation.
|
||||
for (int i = indexPoint2; i < points.length; i++) {
|
||||
@ -68,88 +68,98 @@ public class GrahamScan {
|
||||
* @param x x-coordinate
|
||||
* @param y y-coordinate
|
||||
*/
|
||||
public Point { }
|
||||
public Point {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the x-coordinate
|
||||
*/
|
||||
@Override
|
||||
public int x() {
|
||||
return x;
|
||||
}
|
||||
/**
|
||||
* @return the x-coordinate
|
||||
*/
|
||||
@Override
|
||||
public int x() {
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the y-coordinate
|
||||
*/
|
||||
@Override
|
||||
public int y() { return y; }
|
||||
/**
|
||||
* @return the y-coordinate
|
||||
*/
|
||||
@Override
|
||||
public int y() {
|
||||
return y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the orientation of ordered triplet.
|
||||
*
|
||||
* @param a Co-ordinates of point a <int, int>
|
||||
* @param b Co-ordinates of point a <int, int>
|
||||
* @param c Co-ordinates of point a <int, int>
|
||||
* @return { -1, 0, +1 } if a -→ b -→ c is a { clockwise, collinear; counterclockwise } turn.
|
||||
*/
|
||||
public static int orientation(Point a, Point b, Point c) {
|
||||
int val = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
|
||||
if (val == 0) {
|
||||
return 0;
|
||||
}
|
||||
return (val > 0) ? +1 : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param p2 Co-ordinate of point to compare to.
|
||||
* This function will compare the points and will return a positive integer it the
|
||||
* point is greater than the argument point and a negative integer if the point is
|
||||
* less than the argument point.
|
||||
*/
|
||||
public int compareTo(Point p2) {
|
||||
if (this.y < p2.y) return -1;
|
||||
if (this.y > p2.y) return +1;
|
||||
if (this.x < p2.x) return -1;
|
||||
if (this.x > p2.x) return +1;
|
||||
/**
|
||||
* Finds the orientation of ordered triplet.
|
||||
*
|
||||
* @param a Co-ordinates of point a <int, int>
|
||||
* @param b Co-ordinates of point a <int, int>
|
||||
* @param c Co-ordinates of point a <int, int>
|
||||
* @return { -1, 0, +1 } if a -→ b -→ c is a { clockwise, collinear; counterclockwise }
|
||||
* turn.
|
||||
*/
|
||||
public static int orientation(Point a, Point b, Point c) {
|
||||
int val = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
|
||||
if (val == 0) {
|
||||
return 0;
|
||||
}
|
||||
return (val > 0) ? +1 : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper function that will let us sort points by their polar order
|
||||
* This function will compare the angle between 2 polar Co-ordinates
|
||||
*
|
||||
* @return the comparator
|
||||
*/
|
||||
public Comparator<Point> polarOrder() {
|
||||
return new PolarOrder();
|
||||
}
|
||||
/**
|
||||
* @param p2 Co-ordinate of point to compare to.
|
||||
* This function will compare the points and will return a positive integer it the
|
||||
* point is greater than the argument point and a negative integer if the point is
|
||||
* less than the argument point.
|
||||
*/
|
||||
public int compareTo(Point p2) {
|
||||
if (this.y < p2.y) return -1;
|
||||
if (this.y > p2.y) return +1;
|
||||
if (this.x < p2.x) return -1;
|
||||
if (this.x > p2.x) return +1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
private class PolarOrder implements Comparator<Point> {
|
||||
public int compare(Point p1, Point p2) {
|
||||
int dx1 = p1.x - x;
|
||||
int dy1 = p1.y - y;
|
||||
int dx2 = p2.x - x;
|
||||
int dy2 = p2.y - y;
|
||||
/**
|
||||
* A helper function that will let us sort points by their polar order
|
||||
* This function will compare the angle between 2 polar Co-ordinates
|
||||
*
|
||||
* @return the comparator
|
||||
*/
|
||||
public Comparator<Point> polarOrder() {
|
||||
return new PolarOrder();
|
||||
}
|
||||
|
||||
if (dy1 >= 0 && dy2 < 0) return -1; // q1 above; q2 below
|
||||
else if (dy2 >= 0 && dy1 < 0) return +1; // q1 below; q2 above
|
||||
else if (dy1 == 0 && dy2 == 0) { // 3-collinear and horizontal
|
||||
if (dx1 >= 0 && dx2 < 0) return -1;
|
||||
else if (dx2 >= 0 && dx1 < 0) return +1;
|
||||
else return 0;
|
||||
} else return -orientation(Point.this, p1, p2); // both above or below
|
||||
}
|
||||
}
|
||||
private class PolarOrder implements Comparator<Point> {
|
||||
public int compare(Point p1, Point p2) {
|
||||
int dx1 = p1.x - x;
|
||||
int dy1 = p1.y - y;
|
||||
int dx2 = p2.x - x;
|
||||
int dy2 = p2.y - y;
|
||||
|
||||
/**
|
||||
* Override of the toString method, necessary to compute the difference
|
||||
* between the expected result and the derived result
|
||||
*
|
||||
* @return a string representation of any given 2D point in the format (x, y)
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(" + x + ", " + y + ")";
|
||||
if (dy1 >= 0 && dy2 < 0)
|
||||
return -1; // q1 above; q2 below
|
||||
else if (dy2 >= 0 && dy1 < 0)
|
||||
return +1; // q1 below; q2 above
|
||||
else if (dy1 == 0 && dy2 == 0) { // 3-collinear and horizontal
|
||||
if (dx1 >= 0 && dx2 < 0)
|
||||
return -1;
|
||||
else if (dx2 >= 0 && dx1 < 0)
|
||||
return +1;
|
||||
else
|
||||
return 0;
|
||||
} else
|
||||
return -orientation(Point.this, p1, p2); // both above or below
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override of the toString method, necessary to compute the difference
|
||||
* between the expected result and the derived result
|
||||
*
|
||||
* @return a string representation of any given 2D point in the format (x, y)
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(" + x + ", " + y + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user