使用插入排序 C# 按第二列对锯齿状数组进行排序
Sort jagged array by second column using insertion sort C#
我在 C# 程序中声明了一个锯齿状数组,其中第一列代表年份,第二列代表月数 (1-12),第三列代表该月的一些数据:
double[][] data = new double[3][]
{
new double[] {1930,1931,1931,1931,1931,1931,1931,1931,1931,1931,1931,1931,1931,1932,1932,1932,1932,1932,1932,1932,1932,1932,1932,1932,1932},
new double[] {12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
new double[] {5, 6, 8, 3, 5, 8, 9, 6, 5, 6, 7, 5, 3, 2, 2, 2, 5, 7, 8, 3, 2, 2, 1, 2, 5}
};
如您所见,第一个数组已排序。我想知道如何按第二列对锯齿状数组进行排序,像这样按升序排列。
{1931,1932,1931,1932,1931,1932,1931,1932,1931,1932,1931,1932,1931,1932,1931,1932,1931,1932,1931,1932,1931,1932,1930,1931,1932}
{1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12}
etc...
我的问题是,如何使用插入排序来实现它。它需要是自定义算法,不能使用作为 C#
一部分的 Array.Sort 算法
谢谢
通过定义两个函数,插入排序算法可以很容易地泛化(抽象)到索引上 - 一个用于比较两个索引,一个用于交换两个索引,如下所示:
public static class Algorithms
{
public static void InsertionSort(int start, int count, Func<int, int, int> compare, Action<int, int> swap)
{
for (int i = start + 1, end = start + count; i < end; i++)
for (int j = i; j > start && compare(j - 1, j) > 0; j--)
swap(j - 1, j);
}
}
现在您可以通过比较第二列并像这样交换所有列来实现您的目标:
Algorithms.InsertionSort(0, data[1].Length,
(a, b) => data[1][a].CompareTo(data[1][b]),
(a, b) => { foreach (var col in data) Algorithms.Swap(ref col[a], ref col[b]); });
其中Algorithms.Swap
又是一个小帮手:
public static void Swap<T>(ref T a, ref T b) { T c = a; a = b; b = c; }
我在 C# 程序中声明了一个锯齿状数组,其中第一列代表年份,第二列代表月数 (1-12),第三列代表该月的一些数据:
double[][] data = new double[3][]
{
new double[] {1930,1931,1931,1931,1931,1931,1931,1931,1931,1931,1931,1931,1931,1932,1932,1932,1932,1932,1932,1932,1932,1932,1932,1932,1932},
new double[] {12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
new double[] {5, 6, 8, 3, 5, 8, 9, 6, 5, 6, 7, 5, 3, 2, 2, 2, 5, 7, 8, 3, 2, 2, 1, 2, 5}
};
如您所见,第一个数组已排序。我想知道如何按第二列对锯齿状数组进行排序,像这样按升序排列。
{1931,1932,1931,1932,1931,1932,1931,1932,1931,1932,1931,1932,1931,1932,1931,1932,1931,1932,1931,1932,1931,1932,1930,1931,1932}
{1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12}
etc...
我的问题是,如何使用插入排序来实现它。它需要是自定义算法,不能使用作为 C#
一部分的 Array.Sort 算法谢谢
通过定义两个函数,插入排序算法可以很容易地泛化(抽象)到索引上 - 一个用于比较两个索引,一个用于交换两个索引,如下所示:
public static class Algorithms
{
public static void InsertionSort(int start, int count, Func<int, int, int> compare, Action<int, int> swap)
{
for (int i = start + 1, end = start + count; i < end; i++)
for (int j = i; j > start && compare(j - 1, j) > 0; j--)
swap(j - 1, j);
}
}
现在您可以通过比较第二列并像这样交换所有列来实现您的目标:
Algorithms.InsertionSort(0, data[1].Length,
(a, b) => data[1][a].CompareTo(data[1][b]),
(a, b) => { foreach (var col in data) Algorithms.Swap(ref col[a], ref col[b]); });
其中Algorithms.Swap
又是一个小帮手:
public static void Swap<T>(ref T a, ref T b) { T c = a; a = b; b = c; }