Algorithm 用于有效合并排序的抽象就地合并排序 我正在阅读Robert Sedgewick的C++中的合并排序,并有以下问题。p> static void mergeAB(ITEM[] c, int cl, ITEM[] a, int al, int ar, ITEM[] b, int bl, int br ) { int i = al, j = bl; for (int k = cl; k < cl+ar-al+br-bl+1; k++) { if (i > ar) { c[k] = b[j++]; continue; } if (j > br) { c[k] = a[i++]; continue; } c[k] = less(a[i], b[j]) ? a[i++] : b[j++]; } } static void mergeAB(条目[]c,int cl,条目[]a,int al,int ar,条目[]b,int bl,int br) { int i=al,j=bl; 对于(int k=cl;kar){c[k]=b[j++];继续;} 如果(j>br){c[k]=a[i++];继续;} c[k]=小于(a[i],b[j])?a[i++]:b[j++]; } }
值得注意的基本合并的特点是 内部循环包括两个测试,以确定 已到达两个输入阵列。当然,这两个测试通常 失败了,情况因此迫切需要使用哨兵钥匙 允许删除测试。也就是说,如果元素具有键值 大于所有其他关键点的关键点将添加到a的末端 和aux阵列,可以删除测试,因为当a(b)阵列 耗尽后,哨兵将导致c数组的下一个元素 从b(a)数组中获取,直到合并完成 然而,哨兵的使用并不总是那么容易,因为它 可能不容易知道最大键值,或者因为空间可能 不方便取用 对于合并,有一个简单的补救办法。该方法基于 下面的想法是:假设我们不得不将数组复制到 实现就地抽象,我们只需将第二个数组放入 复制时颠倒顺序(无需额外费用),以便 关联索引从右向左移动。这种安排导致 作为哨兵的阵列中的最大元素 另一个数组 我对上述文本的问题Algorithm 用于有效合并排序的抽象就地合并排序 我正在阅读Robert Sedgewick的C++中的合并排序,并有以下问题。p> static void mergeAB(ITEM[] c, int cl, ITEM[] a, int al, int ar, ITEM[] b, int bl, int br ) { int i = al, j = bl; for (int k = cl; k < cl+ar-al+br-bl+1; k++) { if (i > ar) { c[k] = b[j++]; continue; } if (j > br) { c[k] = a[i++]; continue; } c[k] = less(a[i], b[j]) ? a[i++] : b[j++]; } } static void mergeAB(条目[]c,int cl,条目[]a,int al,int ar,条目[]b,int bl,int br) { int i=al,j=bl; 对于(int k=cl;kar){c[k]=b[j++];继续;} 如果(j>br){c[k]=a[i++];继续;} c[k]=小于(a[i],b[j])?a[i++]:b[j++]; } },algorithm,sorting,mergesort,Algorithm,Sorting,Mergesort,值得注意的基本合并的特点是 内部循环包括两个测试,以确定 已到达两个输入阵列。当然,这两个测试通常 失败了,情况因此迫切需要使用哨兵钥匙 允许删除测试。也就是说,如果元素具有键值 大于所有其他关键点的关键点将添加到a的末端 和aux阵列,可以删除测试,因为当a(b)阵列 耗尽后,哨兵将导致c数组的下一个元素 从b(a)数组中获取,直到合并完成 然而,哨兵的使用并不总是那么容易,因为它 可能不容易知道最大键值,或者因为空间可能 不方便取用 对于合并,有一个简单的补救办法。该方法基于 下面的想法是:
a
数组或b
数组耗尽时”的简写int i = al, j = bl;
for (int k = cl; i <= ar && j <= br; k++)
{
if (a[i] < b[j])
c[k] = a[i++];
else
c[k] = b[j++];
}
while (i <= ar)
c[k++] = a[i++];
while (j <= br)
c[k++] = b[j++];
int i=al,j=bl;
对于(int k=cl;i)
“当a(b)数组耗尽时”是“当a
数组或b
数组耗尽时”的简写
该接口处理的是较大数组的子数组,因此您不能简单地在数组的末端之外写入
代码将数据从两个数组复制到另一个数组中。由于这种复制是不可避免的,我们“顺从于复制数组”意味着我们不情愿地接受必须复制数组是不可避免的
棘手的…这将需要一些时间来弄清楚这意味着什么
切向:这可能不是我编写循环的方式。我倾向于使用:
int i = al, j = bl;
for (int k = cl; i <= ar && j <= br; k++)
{
if (a[i] < b[j])
c[k] = a[i++];
else
c[k] = b[j++];
}
while (i <= ar)
c[k++] = a[i++];
while (j <= br)
c[k++] = b[j++];
int i=al,j=bl;
对于(int k=cl;i a(b)和b(a)
有时,括号用于一次说出一个或多个类似短语:
当a(b)耗尽时,我们从b(a)复制元素
指:
当a耗尽时,我们从b复制元素,
当b耗尽时,我们从a复制元素
哨兵有什么困难
哨兵有两件恼人的事
有时,您的数组数据可能包含所有可能的值,因此没有任何值可以保证比数组中的所有值都大
如果要使用sentinel而不是检查索引以查看是否已使用数组,则需要在数组中留出一个额外的空间来存储sentinel
辞职
我们程序员从不乐于复制(或移动)东西,如果可能的话,把它们留在原来的地方会更好(因为我们懒惰)。
在这个版本的合并排序中,我们已经放弃了不复制周围的东西……我们接受了它。
考虑到我们必须复制,如果我们愿意,我们可以按相反的顺序复制(当然也可以按相反的顺序使用副本),因为这是免费的(*)
(*)在这个抽象级别是免费的,一些实际CPU的成本可能很高。几乎总是在性能方面。a(b)和b(a)
有时,括号用于一次说出一个或多个类似短语:
当a(b)耗尽时,我们从b(a)复制元素
指:
当a耗尽时,我们从b复制元素,
当b耗尽时,我们从a复制元素
哨兵有什么困难
哨兵有两件恼人的事
有时,您的数组数据可能包含所有可能的值,因此没有任何值可以保证比数组中的所有值都大
如果要使用sentinel而不是检查索引以查看是否已使用数组,则需要在数组中留出一个额外的空间来存储sentinel
辞职
我们程序员从来都不喜欢复制(或移动)东西,把它们留在自己喜欢的地方