Algorithm k路合并排序基本情况
我不理解这个来自Geeksforgeks的k-way合并排序的特定示例代码。 更具体地说,我不明白divide()的基本情况中for循环中的“n”是什么。是每个数组中的学生数吗?(在本例中为4) 另外,您能否解释一下divide()中的for循环与divide()进程相关的作用?+基本情况(l==r)应该是什么意思 多谢各位 方法:一旦我们开始将k数组视为合并排序算法的中间状态,想法就变得清晰了。 因为有k个数组已经排序,所以合并k个数组。创建一个递归函数,该函数将接受k个数组,并将它们分成两部分,然后用每一半递归调用该函数。基本情况是k值小于3时。 请参阅本文以在O(n)时间内合并两个数组 算法:初始化大小为N*k的输出数组。 调用函数divide。设l和r表示要合并的数组的范围,因此在0到k-1之间变化。 在每一步中,我们递归调用范围的左半部和右半部,以便对它们进行排序并存储在输出数组中。 然后,我们合并左半部和右半部。对于合并,我们需要确定输出数组中左右两半的索引范围。我们很容易找到。 左侧部分将从输出数组的索引l*n开始。 类似地,右侧部分将从输出数组的索引((l+r)/2+1)*n开始Algorithm k路合并排序基本情况,algorithm,sorting,Algorithm,Sorting,我不理解这个来自Geeksforgeks的k-way合并排序的特定示例代码。 更具体地说,我不明白divide()的基本情况中for循环中的“n”是什么。是每个数组中的学生数吗?(在本例中为4) 另外,您能否解释一下divide()中的for循环与divide()进程相关的作用?+基本情况(l==r)应该是什么意思 多谢各位 方法:一旦我们开始将k数组视为合并排序算法的中间状态,想法就变得清晰了。 因为有k个数组已经排序,所以合并k个数组。创建一个递归函数,该函数将接受k个数组,并将它们分成两部
导入java.util.*;
类GFG{
静态int n=4;
//履行的职能
//合并操作
静态无效合并(
int l、int r、int[]输出)
{
//存储起点
//左右数组的构造
int l_in=l*n,r_in
=((l+r)/2+1)*n;
//要存储左侧和右侧的大小
//右数组
int l_c=((l+r)/2-l+1)*n;
int r_c=(r-(l+r)/2)*n;
//要临时存储左侧的数组
//和右数组
int l_arr[]=新int[l_c],
r_arr[]=新整数[r_c];
//在左数组中存储数据
对于(int i=0;i
发件人:我认为这是
合并排序的高级版本。这里是场景,我们有k
排序数组,每个数组中都有n
元素(您称之为学生)。目标是拥有所有元素的单个排序数组(output
),其大小为k*n
。由于k
数组已排序,因此我们只需要一个算法来合并它们。为此,在递归函数divide(l,r,output,arr)
中,我们将l-th
到r-th
数组分成两组,并递归调用divide。例如,对于k=3
我们有l=0
和r=2
。在除法函数中,因为l=r
我们跳过第一个if,调用两个函数divide(0,1,output,arr)
和divide(2,2,output,arr)
。同样,在第一个函数调用中,我们调用divide(0,0,output,arr)
和divide(1,1,output,arr)
。现在,当我们有l==r
时,我们应该保存l-th(等于r-th)数组以进行输出(注意merge
函数是一个就地函数)。为此,请记住将2d
数组a[n][m]
转换为1d
数组B[n*m]
我们可以使用B[i*n+j]
访问a[i][j]
。为了进一步澄清,我在divide函数中添加了一些打印:
static void divide(int l, int r, int[] output,
int arr[][])
{
if (l == r) {
/* base step to initialize the output
array before performing merge
operation */
for (int i = 0; i < n; i++)
output[l * n + i] = arr[l][i];
System.out.println("After writing to output:");
for (int i = 0; i < n * k; i++)
System.out.print(output[i] + " ");
System.out.println()
return;
}
// to sort left half
divide(l, (l + r) / 2, output, arr);
// to sort right half
divide((l + r) / 2 + 1, r, output, arr);
// merge the left and right half
merge(l, r, output);
System.out.print("After Merge:");
for (int i = 0; i < n * k; i++)
System.out.print(output[i] + " ");
System.out.println();
}
static void divide(int l, int r, int[] output,
int arr[][])
{
if (l == r) {
/* base step to initialize the output
array before performing merge
operation */
for (int i = 0; i < n; i++)
output[l * n + i] = arr[l][i];
System.out.println("After writing to output:");
for (int i = 0; i < n * k; i++)
System.out.print(output[i] + " ");
System.out.println()
return;
}
// to sort left half
divide(l, (l + r) / 2, output, arr);
// to sort right half
divide((l + r) / 2 + 1, r, output, arr);
// merge the left and right half
merge(l, r, output);
System.out.print("After Merge:");
for (int i = 0; i < n * k; i++)
System.out.print(output[i] + " ");
System.out.println();
}
After writing to output:
[5, 7, 15, 18, 0, 0, 0, 0, 0, 0, 0, 0] # after divide(0, 0, output, arr)
After writing to output:
[5, 7, 15, 18, 1, 8, 9, 17, 0, 0, 0, 0] # after divide(1, 1, output, arr)
After Merge:
[1, 5, 7, 8, 9, 15, 17, 18, 0, 0, 0, 0] # after merge(0, 1, output)
After writing to output:
[1, 5, 7, 8, 9, 15, 17, 18, 1, 4, 7, 7] # after divide(2, 2, output, arr)
After Merge:
[1, 1, 4, 5, 7, 7, 7, 8, 9, 15, 17, 18] # after merge(0, 2, output)