今天,我的教授给了我们2个带回家的问题作为C中即将推出的阵列单元的练习,我想知道这两个问题的排序算法究竟是什么样的,以及他们的Big O是什么。 现在,我不是来这里只是期待答案,我已经 ALREADY 解决了这些问题,但我的答案中没有自信所以我会发帖他们对每个问题都提出质疑,如果我错了,请纠正我,并在思考中解释我的错误。
问题1:
如果我们决定一次浏览一个数组(框)元素(文件夹)。从第一个元素开始并将其与下一个元素进行比较。然后,如果它们是相同的,则比较结束,但是如果两者不相等则继续比较接下来的两个ELEMENTS [2]和[3]。重复此过程,并在最后两个元素进行比较后停止,并注意数组已经按姓氏排序,我们正在寻找相同的名字!示例:[Harper Steven,Hawking John,Ingleton Steven]
我相信答案:
我相信它是O(n)因为它只是将数组[0]与数组[1]进行比较,然后将数组[2]转换为数组[3]等。此过程是线性的,并持续到最后两个进行比较。绝对不会登录,因为我们没有乘以或潜水2。
最终问题: 假设我们有一个文件夹,每个文件夹包含一个人的信息。如果我们想要寻找具有相同名字的人,我们可以首先在框中的第一个文件夹上放置一个贴纸,然后以有序的方式浏览文件夹,直到找到具有相同名字的人。如果我们找到一个具有相同名称的文件夹,我们将该文件夹移动到带有标签的文件夹旁边。一旦我们发现一个案例,其中两个人有相同的名字,我们停下来睡觉,因为我们很懒。如果第一次搜索失败,我们只需删除贴纸并将其放在下一个文件夹中,然后继续我们之前的操作。我们重复这个过程,直到贴纸在最后一个文件夹中,我们没有两个同名的人。
此数组未排序,并将第一个文件夹与贴纸文件夹[0]与下一个i文件夹[i]元素进行比较。
我的回答:
我觉得这不能是O(n),但也许是O(n ^ 2),它有点像我们有一个数组,然后我们不断重复这个过程,其中n与输入的平方成正比(文件夹)。我可能通过>。>
错了答案 0 :(得分:1)
你对这两个问题都是正确的......但这有助于更严格地解释事情。我不知道你班上的标准是什么;你可能不需要一个实际的证明,但显示更详细的推理而不是“我们没有乘以或除以两个”从不伤害。所以......
在第一个问题中,这里显然没有发生任何事情,只有比较,所以这就是我们必须要考虑的事情。
最糟糕的情况显然是你必须经历整个阵列。
因此,在这种情况下,您必须比较a[0] == a[1]
,然后a[1] == a[2]
,...,a[N-1] == a[N]
。对于每个N-1
元素,有1个比较。这是N-1
步骤,显然是O(N)
。
数组排序的事实在这里无关紧要。 (当然因为它们没有按你的搜索键排序 - 也就是说,它们按姓氏排序,但是你用名字进行比较 - 这已经很明显了。)
在第二个问题中,这里发生了两件事:比较,然后是移动。
对于比较,最糟糕的情况是您必须进行所有N
次搜索,因为没有匹配项。正如您所说,我们从a[0]
与a[1]
,...,a[N]
开始;然后是a[1]
与a[2]
,...,a[N]
等。所以,N-1
比较,然后是N-2
,依此类推至0
。因此,比较总数为sum(0…N-1)
,即N*(N-1)/2
或N^2/2 - N/2
,即O(N^2)
。
对于移动,最糟糕的情况是您在a[0]
和a[N]
之间找到了匹配项。在这种情况下,您必须将a[N]
与a[N-1]
交换,然后将a[N-1]
与a[N-2]
交换,依此类推,直到您将a[2]
与{{1}交换为止}}。那么,a[1]
交换N-1
,您可以忽略它,因为您已经有O(N)
个术语。
作为旁注,我不能从你的描述中确定你是在谈论来自O(N^2)
的数组,还是长度为N的数组,所以a[0…N]
,所以可能会有上述两个中的一个错误。但要向自己证明它没有任何区别应该很容易。
答案 1 :(得分:1)
场景2,找到任意值的两个匹配项的方法确实是“二次”的。每个通道寻找一个候选者与所有其余元素的匹配是O(n)。但你重复 n次。 n的值随着时间的推移而下降,因此详细的比较数将更接近n +(n-1)+(n-2)+ ... 1,即(n + 1)×(n / 2)或½(n²) + n)但我们关心的只是曲线的整体形状,所以不要担心低阶项或系数。它是O(n²)。