Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 比较两种常用的比较算法及其大O帮助_C++_C_Big O - Fatal编程技术网

C++ 比较两种常用的比较算法及其大O帮助

C++ 比较两种常用的比较算法及其大O帮助,c++,c,big-o,C++,C,Big O,今天,我的教授给了我们两个带回家的问题,作为即将到来的C语言数组单元的练习,我想知道这两个问题的排序算法到底是什么样的,它们的大O是什么现在,我来这里不仅仅是期待答案,我已经解决了它们,但我对我的答案不自信,所以我会把它们贴在每个问题上,如果我错了,请纠正我并解释我的思考错误 问题1: 如果我们决定逐个检查数组的(框)元素(文件夹)。从第一个元素开始,并将其与下一个元素进行比较。然后,如果它们相同,则比较结束,但是如果两者不相等,则继续比较下两个元素[2]和[3]。重复此过程,并在比较最后两个元

今天,我的教授给了我们两个带回家的问题,作为即将到来的C语言数组单元的练习,我想知道这两个问题的排序算法到底是什么样的,它们的大O是什么现在,我来这里不仅仅是期待答案,我已经解决了它们,但我对我的答案不自信,所以我会把它们贴在每个问题上,如果我错了,请纠正我并解释我的思考错误

问题1:

如果我们决定逐个检查数组的()元素(文件夹)。从第一个元素开始,并将其与下一个元素进行比较。然后,如果它们相同,则比较结束,但是如果两者不相等,则继续比较下两个元素[2]和[3]。重复此过程,并在比较最后两个元素后停止,请注意,数组已按姓氏排序,我们正在查找相同的姓氏!示例:[哈珀·史蒂文、霍金·约翰、英格尔顿·史蒂文]

我相信的答案:

我认为它是O(n),因为它只是遍历数组的元素,比较数组[0]和数组[1],然后比较数组[2]和数组[3]等等。这个过程是线性的,一直持续到最后两个比较为止。绝对不是logn,因为我们不是乘2或跳水

最后一个问题: 假设我们有一盒文件夹,每个文件夹包含一个人的信息。如果我们想寻找同名的人,我们可以先在盒子里的第一个文件夹上贴上一张标签,然后依次浏览文件夹,直到找到同名的人。如果我们找到一个同名文件夹,我们会将该文件夹移到带有标签的文件夹旁边。一旦我们发现两个人同名,我们就会停下来睡觉,因为我们很懒。但是,如果第一次搜索失败,我们只需删除标签并将其放在下一个文件夹中,然后像前面一样继续。我们重复这个过程,直到在一个场景中,我们并没有两个同名的人,标签出现在最后一个文件夹中

此数组未排序,并将第一个带有标签文件夹[0]的文件夹与下一个i文件夹[i]元素进行比较

我的答案:


我觉得这不可能是O(n),但可能是O(n^2),它有点像我们有一个数组,然后我们不断重复这个过程,其中n与输入(文件夹)的平方成正比。通过>/p>我可能是错的,你在这两个问题上都是对的……但这将有助于更严格地解释事情。我不知道你们班的标准是什么;你可能不需要一个实际的证据,但展示比“我们不是乘二或除二”更详细的推理从来不会有什么坏处。所以


在第一个问题中,除了比较,这里显然什么都没有发生,所以这就是我们必须计算的

最坏的情况显然是你必须遍历整个数组

因此,在这种情况下,您必须比较
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]
a[1]
交换。这就是
N-1
swap,也就是
O(N)
,你可以忽略它,因为你已经得到了一个
O(N^2)
术语



作为旁注,从您的描述中,我不确定您所说的是来自
a[0…N]
的数组,还是长度为N的数组,因此
a[0…N-1]
,因此上述两种情况中都可能存在一个off-by-one错误。但是,向自己证明这一点应该很容易。

场景2,一种寻找任意值的两个匹配项的方法,确实是“二次的”。寻找一个候选元素与所有其他元素匹配的每个过程都是O(n)。但你重复了n次。n的值会随着时间的推移而下降,因此详细的比较次数会更接近n+(n-1)+(n-2)+…1,即(n+1)×n/2)或½(n²+n),但我们关心的只是曲线的整体形状,所以不要担心低阶项或系数。是O(n²)。

我真的很抱歉,我是想说元素!我已经修复了它,问题中应该没有更多的错误。在第一个问题中,您说“注意数组已经排序”。第二个问题也是这样吗?它是按名字排序的,还是按姓氏排序的?(这可能会改变“…以有序的方式…”的含义)除此之外,你是对的,我们必须进行N次搜索(无论搜索需要多长时间),然后进行1次交换(