我正在参加算法课程,最新的作业真的让我很难受。本质上,赋值是实现一个合并排序版本,它不会像CLRS中的实现那样分配尽可能多的临时内存。我应该通过在开头只创建一个临时数组来做到这一点,并在拆分和合并时将所有临时内容放入其中。
我还应该注意,该类的语言是Lua,这很重要,因为唯一可用的数据结构是表。它们就像Java映射一样,它们来自键值对,但它们就像数组一样,你不需要成对插入东西 - 如果你只插入一个被视为值的东西,它的关键将是它的索引将使用真实数组的语言。至少我是这样理解的,因为我也是Lua的新手。此外,任何东西,原语,字符串,对象等都可以成为关键 - 甚至是同一个表中的不同类型。
无论如何,有两件令我困惑的事情:
首先,它是如何完成的?您是否只是在每次拆分和合并递归时都会覆盖临时数组?
其次,我对作业说明感到困惑(我正在免费审核课程,所以我不能问任何工作人员)。以下是说明:
编写一个顶级过程merge_sort,以ar-为参数 射线来排序。它应声明一个临时数组,然后调用merge_sort_1, 一个四个参数的过程:要排序的数组,用作tem-的数组 诗歌空间,以及此调用的开始和结束索引 merge_sort_1应该有效。
现在编写merge_sort_1,它计算开始结束的中点 interval,并为每一半做一次递归调用。之后呢 调用merge来合并两半。 您现在编写的合并程序将是永久性的功能 数组和临时数组,开始,中点和结束。 它维护临时数组的索引,并将索引i,j保存到每个数组中 (已排序)永久阵列的一半。 它需要从头到尾遍历临时阵列,复制 来自永久阵列的下半部分或来自的永久数组的值 永久阵列的上半部分。它选择较低的i处的值 如果小于或等于上半部分j的值,则为一半 进步我如果小于,则选择上半部分j的值 下半部分的i值,并提前j。 永久阵列的一部分用完后,请务必复制其余部分 另一部分教科书使用具有无限值∞的技巧 避免检查任一部分是否用完。但是,这个伎俩很难 在这里申请,你会把它放在哪里? 最后,复制临时数组中从开始到结束的所有值 回到永久阵列。
数字2令人困惑,因为我不知道merge_sort_1应该做什么,以及为什么它必须是与merge_sort不同的方法。我也不知道为什么需要传递开始和结束索引。事实上,也许我误读了一些东西,但说明听起来像merge_sort_1并没有做任何实际的工作。
此外,整个作业令人困惑,因为我没有从指令中看到进行拆分的原因是制作原始数组的两半。或者我误解了mergesort?
我希望我有一些道理。谢谢大家!
答案 0 :(得分:1)
首先,我会确保你理解mergesort 查看this解释,使用精美的动画来帮助您理解它。
这是它们的伪代码版本:
# split in half
m = n / 2
# recursive sorts
sort a[1..m]
sort a[m+1..n]
# merge sorted sub-arrays using temp array
b = copy of a[1..m]
i = 1, j = m+1, k = 1
while i <= m and j <= n,
a[k++] = (a[j] < b[i]) ? a[j++] : b[i++]
→ invariant: a[1..k] in final position
while i <= m,
a[k++] = b[i++]
→ invariant: a[1..k] in final position
了解他们如何使用b来保存数据的临时副本? 老师想要的是你传递一张桌子用于这个临时存储。
这会清除作业吗?
答案 1 :(得分:1)
你的主要排序例程如下:(抱歉,我不认识Lua,所以我会写一些Javaish代码)
void merge_sort(int[] array) {
int[] t = ...allocate a temporary array...
merge_sort_1(array, 0, array.length, t);
}
merge_sort_1
接受一个数组排序,一些开始和结束索引,以及一个用于某些临时空间的数组。它执行实际的分而治之的调用并调用merge
例程。请注意,递归调用需要转到merge_sort_1
而不是merge_sort
,因为您不希望在每个递归级别上分配数组,只需在合并排序过程开始时分配一次。 (这是将合并排序分为两个例程的重点。)
我会留给你写一个merge
程序。它应该采用包含2个已排序子部件和临时数组的原始数组,并对原始数组进行排序。最简单的方法是合并到临时数组中,然后在完成后将其复制回来。
答案 2 :(得分:0)
首先,它是如何完成的?你呢 只是继续覆盖临时数组 每次递归分裂和 合并?
是的,临时数组不断被覆盖。在合并阶段使用临时数组来保存合并结果,然后在合并结束时将其复制回永久数组。
2号令人困惑,因为我有 不知道merge_sort_1应该是什么 要做,为什么它必须是一个 merge_sort的不同方法。
merge_sort_1
是递归合并排序的递归中心。 merge_sort
只是一个便利函数,创建临时数组并填充初始开始和结束位置。
我也不知道为什么需要这样做 传递了开始和结束索引。在 事实上,也许我误读了一些东西,但是 说明听起来像 merge_sort_1没有做任何实际的工作。
此外,整个作业是 令人困惑,因为我没有看到 分裂的指示 完成原来的两半 阵列。或者我误解了 归并排序
递归函数merge_sort_1
仅适用于传入数组的一部分。它所处理的部分由起始和结束索引定义。开始和结束之间的中点是如何拆分数组,然后在递归调用时再次拆分。在完成对上半部分和下半部分的递归调用之后,将两半合并到临时数组中,然后将其复制回永久数组。
我能够按照描述在Lua中编写合并排序,并可以评论我的实现。它看起来似乎是通过说明写成,好像它们是关于教师实施的评论。
这是merge_sort
函数。正如我所说,它只是一种便利功能,我觉得这不是问题的关键。
-- Write a top level procedure merge_sort that takes as its argument
-- the array to sort.
function merge_sort(a)
-- It should declare a temporary array and then call merge_sort_1,
-- a procedure of four arguments: The array to sort, the one to use
-- as temporary space, and the start and finish indexes within which
-- this call to merge_sort_1 should work.
merge_sort_1(a,{},1,#a)
end