按c#中第一个元素的升序排序2d数组行

我需要按照第一个元素的升序对2d数组行进行排序,就像在示例中一样

{{5,7,6},{2,9,6},{4,8,1}} – > {{2,9,6},{4,8,1},{5,7, 6}}

我可以在行中找到最大元素,但我现在不知道如何对行进行排序。

public double[] maxInRow(double[,] n) { double[] result = new double[n.GetLength(0)]; for (int i = 0; i < n.GetLength(0); i++) { double max = 0; for (int j = 0; j < n.GetLength(1); j++) { if (max < n[i,j]) { max = n[i,j]; } } result[i] = max; } return result; } 

你能建议吗?

提前致谢!

令人遗憾的是,你错过了linq的力量,它是.Net framework最好的组件之一,你可以试试这个

 double[][] x = new double[2][]; x[0] = new double[] { 5, 2, 5 }; x[1] = new double[] { 6, 8, 3 }; x[2] = new double[] { 8, 3, 6 }; var sortedByFisrtVal = x.OrderBy(y => y[0]); var sortedBySecondVal = x.OrderBy(y => y[1]); //trying to guess maybe this is better var sorted = x.OrderBy(y => y[0]).ThenBy(y => y[1]).ThenBy(y => y[2]); 

如果性能不是很关键,那么您可以将2D数组转换为行数组,通过OrderBy对它们进行排序,提供Max作为条件,然后将结果转换回2D数组:

  private static T[][] Convert(T[,] source, int firstDim, int secondDim) { T[][] result = new T[firstDim][]; for (int i = 0; i < firstDim; i++) { T[] temp = new T[secondDim]; for (int j = 0; j < secondDim; j++) { temp[j] = source[i, j]; } result[i] = temp; } return result; } private static T[,] ConvertBack(T[][] source, int firstDim, int secondDim) { var result = new T[firstDim, secondDim]; for (int i = 0; i < firstDim; i++) { for (int j = 0; j < secondDim; j++) { result[i, j] = source[i][j]; } } return result; } // usage sample double[,] array = { { 5, 7, 6 }, { 2, 9, 6 }, { 4, 8, 1 } }; int firstDim = array.GetUpperBound(0) + 1; int secondDim = array.GetUpperBound(1) + 1; double[][] jagged = Convert(array, firstDim, secondDim); // actual sort is done here! double[][] sorted = jagged.OrderByDescending(row => row.Max()).ToArray(); double[,] result = ConvertBack(sorted, firstDim, secondDim); 

你不需要任何额外的方法。 如上所述,只为二维数组实现Sort方法。

此排序算法与1D数组的排序算法相同,除了您还需要第三个循环来交换行的元素。

 public static void Sort(double[,] n) { for (int i = 0; i < n.GetLength(0) - 1; i++) { for (int j = i; j < n.GetLength(0); j++) { if (n[i, 0] > n[j, 0]) // sort by ascending by first index of each row { for (int k = 0; k < n.GetLength(1); k++) { var temp = n[i, k]; n[i, k] = n[j, k]; n[j, k] = temp; } } } } } 

你可以这样称呼它。

 Sort(your2dArray); 

请注意,算法可能会变得非常慢,如Alexei Levenkov所述。 因此,如果性能在这里不重要,请使用它。

如果使用锯齿状arrays而不是2Darrays,则可以使事情变得更快。 linq还支持1D数组(因此也是锯齿状数组),它实现了IEnumerable,你可以使用OrderBy快速排序。

2d数组不是用于排序,但无论如何,这是你如何做到这一点

 public static class MyAlgorithms { public static void SortByFirstColumn(this T[,] array, IComparer comparer = null) { // Indirect sorting var sortIndex = new int[array.GetLength(0)]; for (int i = 0; i < sortIndex.Length; i++) sortIndex[i] = i; if (comparer == null) comparer = Comparer.Default; Array.Sort(sortIndex, (a, b) => comparer.Compare(array[a, 0], array[b, 0])); // Reorder the array using "in situ" algorithm var temp = new T[array.GetLength(1)]; for (int i = 0; i < sortIndex.Length; i++) { if (sortIndex[i] == i) continue; for (int c = 0; c < temp.Length; c++) temp[c] = array[i, c]; int j = i; while (true) { int k = sortIndex[j]; sortIndex[j] = j; if (k == i) break; for (int c = 0; c < temp.Length; c++) array[j, c] = array[k, c]; j = k; } for (int c = 0; c < temp.Length; c++) array[j, c] = temp[c]; } } } 

并按如下方式使用它

 double[,] data = { { 5, 7, 6 }, { 2, 9, 6 }, { 4, 8, 1 } }; data.SortByFirstColumn(); 

此实现不会受到影响。 有关它的工作原理和一些其他选项的更多解释,请参阅我的答案如何对大型2d数组进行排序C#

如果您想按第一列排序,然后按第二列排序,再按第三列排序,依此类推所有列,您可以这样:

 void Main() { var input = new double[,] {{5,7,6},{2,9,6},{2,5,6},{4,8,1}}; Sort(input); // Input is now: // {{2,5,6},{2,9,6},{4,8,1},{5,7,6}} } public T[,] Sort(T[,] data) where T : IComparable { // Transform to array of arrays. var rows = new T[data.GetLength(0)][]; for (var i = 0; i< data.GetLength(0); ++i) { rows[i] = new T[data.GetLength(1)]; for (var j = 0; j < data.GetLength(1); ++j) rows[i][j] = data[i, j]; } // Sort rows using a custom array comparer. Array.Sort(rows, new ArrayComparer()); // Write data back to input array. for (var i = 0; i< data.GetLength(0); ++i) for (var j = 0; j < data.GetLength(1); ++j) data[i, j] = rows[i][j]; return data; } public class ArrayComparer : IComparer where T : IComparable { public int Compare(T[] x, T[] y) { var comparer = Comparer.Default; // Compare elements as long as they're different. for(var i = 0; i < x.Length; ++i) { var compareResult = comparer.Compare(x[i], y[i]); if (compareResult != 0) return compareResult; } return 0; } }