Java 使用Arrays.sort按最后一行对二维数组排序

Java 使用Arrays.sort按最后一行对二维数组排序,java,algorithm,sorting,matrix,Java,Algorithm,Sorting,Matrix,在Java中是否可以使用Arrays.sort(,)按最后一行对2d数组进行排序。下面的代码片段非常适合按最后一列排序,但它似乎没有调整按最后一行排序的方法 我的第一个想法是使用将列转换为行,进行排序,然后将行转换为列。对于非常大的阵列有更好的方法吗 int[][] twoDim = { {1, 2, 3}, {3, 7, 11}, {8, 9, 16}, {4, 2,8}, {5, 3, 9} }; Arrays.sort(twoDim, new Comparator<int[]>

在Java中是否可以使用Arrays.sort(,)按最后一行对2d数组进行排序。下面的代码片段非常适合按最后一列排序,但它似乎没有调整按最后一行排序的方法


我的第一个想法是使用将列转换为行,进行排序,然后将行转换为列。对于非常大的阵列有更好的方法吗

int[][] twoDim = { {1, 2, 3}, {3, 7, 11}, {8, 9, 16}, {4, 2,8}, {5, 3, 9} };
Arrays.sort(twoDim, new Comparator<int[]>() {
     @Override
     public int compare(int[] o1, int[] o2) {
         return ((Integer) o1[2]).compareTo(o2[2]);
     }
});
int[]twoDim={{1,2,3},{3,7,11},{8,9,16},{4,2,8},{5,3,9};
sort(twoDim,新的Comparator(){
@凌驾
公共整数比较(整数[]o1,整数[]o2){
返回((整数)o1[2])。与(o2[2])比较;
}
});
让我们详细说明一下整个情况: 这就是我的数组初始化时的位置,通过行和列,您可以想象这个数据集如下所示:


{1,2,3},//第一行有三列
{3,7,11},//第二行有三列
{8,9,16},
{4,2,8},
{5,3,9}//最后一行有三列

按最后一行排序意味着重新排列第一列和第二列的位置,因为5大于3。所以在重新排列数据集之后,它看起来像:

2,1,3
7,3,11
9,8,16
2,4,8
3,5,9//现在它是按最后一行排序的(第一列和第二列的位置已更改,碰巧第三列已经位于正确的位置)

如果我正确理解您所说的列和行的含义,则无法回答此问题

如果您这样查看数据集:

1, 2, 3
3, 7, 11
8, 9, 16
4, 2, 8
5, 3, 9
现在,如果按最后一行对其进行排序,将得到以下结果:

{2, 7, 9, 2, 3}, {1,3,8,4,5}, {3, 11, 16, 8, 9}
如果将
4,2,8
行替换为
5,3,9
行,则显然不会出现这种情况。 所以,你要么制定一个标准的订单,要么找到一个不同的方法来解决你所面临的实际问题

如果你在处理矩阵,我强烈推荐一个有趣的问题

我会通过实现一个。这些变化主要在
分区
函数中:

  • 使用矩阵的最后一行作为要排序的数组
  • 交换两个元素时,实际上是交换矩阵的两列
下面是一个实现:

public void qsortOnLastRow(int[][] matrix, int left, int right) {
    if (left < right) {
        int i = partition(matrix, left, right);
        qsortOnLastRow(matrix, left, i - 1);
        qsortOnLastRow(matrix, i + 1, right);
    }
}

public int partition(int[][] matrix, int left, int right) {
    int lastrow = matrix.length - 1;
    int pivotValue = matrix[lastrow][left];
    int i = left;
    for (int j = left + 1; j <= right; j++) {
        if (matrix[lastrow][j] <= pivotValue) {
            i++;
            swapColumns(matrix, i, j);
        }
    }
    swapColumns(matrix, left, i);
    return i;
}

public void swapColumns(int[][] matrix, int c0, int c1) {
    if (c0 != c1) {
        for (int i = 0; i < matrix.length; i++) {
            int t = matrix[i][c0];
            matrix[i][c0] = matrix[i][c1];
            matrix[i][c1] = t;
        }
    }
}
public void qsortOnLastRow(int[][]矩阵,int左,int右){
if(左<右){
int i=分区(矩阵,左,右);
qsortOnLastRow(矩阵,左,i-1);
qsortOnLastRow(矩阵,i+1,右);
}
}
公共int分区(int[][]矩阵,int左,int右){
int lastrow=matrix.length-1;
int pivotValue=矩阵[lastrow][left];
int i=左;

对于(int j=left+1;j记住,二维数组是数组的数组。每个排序算法都需要一个工具来移动要排序的条目。按最后一列排序的解决方案是有效的,因为
数组。sort
将内部数组视为要排序的对象。您称之为按最后一行排序的算法没有等价的对象,而应该表示列

所以你有两个选择:

  • 实现您自己的排序算法,一次交换整个列,但请使用教科书算法

  • 转置你的矩阵。但是记住,如果可以在整个程序中交换第一个和第二个索引的含义,这可能是免费的


  • 请定义一下列和行的含义,它们让我很困惑。“我的第一个想法是使用将列转换为行,进行排序,然后将行转换为列。”这听起来是实现所需的最佳方法。这是一个非常缓慢的过程。快速排序的最坏情况复杂性为O(n^2)对n个元素进行排序,其平均大小写复杂度为O(n*logn)对n个元素进行排序。因为,在这种情况下,您必须交换整列,因此复杂性更差。通常,比较量用于描述排序算法的复杂性,但在这里交换量更重要。因此,另一种算法可能更好。@jmg:swap此处涉及和整列:
    swapColumn
    h作为复杂性
    O(m)
    (假设矩阵有m行)。你会推荐哪种算法?几乎每个排序算法都使用比较和交换。啊,当我写这篇文章时,你的答案说了一些不同的东西;-)一些东西,比如O(n^2 log n)。没关系,我可以同意。取决于“预排序”在数组中,尝试冒泡排序可能是值得的,因为它通常需要移动对象的次数要少得多。虽然快速排序会移动对象,但由于分区的原因,它会退出很多次。但是要给出明确的答案,必须做好基准测试。@jmg:对不起,我在回复您的评论之前编辑了我的答案:)(是的,以前它是错误的,因为我有
    O(n^2 lg n)
    )。我明白你关于交换的观点:我同意需要一些基准来确定哪种方法更好。