Arrays.sort(pointsBySlope,p.SLOPE_ORDER)是否依赖于pointsBySlope []是什么?

时间:2014-07-18 16:17:46

标签: java sorting

Point是一个具有两个实例变量的类,它们是一个点的坐标。 (X,Y) Point实现Comparable接口。但除了通过它们的坐标进行比较之外,任何点(x1,y1)也可以与它们相对于另一个点(x0,y0)的相对斜率(x2,y2)进行比较。以下是Point类:

import java.util.Comparator;

public class Point implements Comparable<Point> {

// compare points by slope
public final Comparator<Point> SLOPE_ORDER = new Ordering(); 
private final int x;                              // x coordinate
private final int y;                              // y coordinate

// create the point (x, y)
public Point(int x, int y) {
    /* DO NOT MODIFY */
    this.x = x;
    this.y = y;
}

private class Ordering implements Comparator<Point>{

    @Override
    public int compare(Point p1, Point p2) {
        if(slopeTo(p1) - slopeTo(p2) < 0) return -1;
        else if(slopeTo(p1) - slopeTo(p2) > 0) return 1;
        else return 0;
    }

}

// slope between this point and that point
public double slopeTo(Point that) {
    /* YOUR CODE HERE */
    if(this.y == that.y && this.x == that.x) return Double.NEGATIVE_INFINITY;
    else if(this.y == that.y) return 0;
    else if(this.x == that.x) return Double.POSITIVE_INFINITY;
    else return ((double)that.y - (double)this.y)/((double)that.x - (double)this.x);
}

// is this point lexicographically smaller than that one?
// comparing y-coordinates and breaking ties by x-coordinates
public int compareTo(Point that) {
    /* YOUR CODE HERE */
    if(this.y < that.y){
        return -1;
    }else if(this.y > that.y){
        return 1;
    }else{
        if(this.x < that.x) return -1;
        else if(this.x > that.x) return 1;
        else return 0;
        }
    }
}

现在我写了一个简单的测试类来测试斜率排序是否有效。

public class Test {

public static void main(String[] args) {
    In in = new In(args[0]);
    int N = in.readInt();
    Point[] points = new Point[N];
    Point[] pointsBySlope = new Point[N];
    for (int i = 0; i < N; i++) {
        int x = in.readInt();
        int y = in.readInt();
        points[i] = new Point(x, y);
        pointsBySlope[i] = points[i];
    }
    Arrays.sort(points);
    Arrays.sort(pointsBySlope);

    Point p = points[2];
    Arrays.sort(pointsBySlope, p.SLOPE_ORDER);

    p = points[3];
    Arrays.sort(pointsBySlope, p.SLOPE_ORDER);
    for(int i=0;i<pointsBySlope.length;i++){
        System.out.println(pointsBySlope[i].toString()+" , ");
    }
    System.out.println("\n\n"+"=================================");
    Arrays.sort(pointsBySlope);
    Arrays.sort(pointsBySlope, p.SLOPE_ORDER);
    for(int i=0;i<pointsBySlope.length;i++){
        System.out.println(pointsBySlope[i].toString()+" , ");
    }
}

}

输出

(19000, 10000) , 
(18000, 10000) , 
(14000, 10000) , 
(21000, 10000) , 
(32000, 10000) , 
(1234, 5678) , 

(19000, 10000) , 
(14000, 10000) , 
(18000, 10000) , 
(21000, 10000) , 
(32000, 10000) , 
(1234, 5678) ,

为什么两种情况下的输出都不同?最初如何按自然顺序对pointsBySlope数组进行排序,然后通过SLOPE_ORDER进行排序,直接按SLOPE_ORDER排序会产生不同的输出?

1 个答案:

答案 0 :(得分:1)

在两种排序中,p(19000, 10000)。然后,(14000, 10000), (18000, 10000), (21000, 10000), (32000, 10000)中的每一个都有p的“0的斜率”。这意味着您的比较器不会重新排序这些点;它会在排序之前以任何顺序离开它们。对于你的第二个输出,这恰好是点的自然顺序;对于第一个输出,它不是。