c语言桶排序对链表,关于算法:如果我们使用链表实现存储桶,存储桶排序的复杂度如何为O(n + k)?...

我很好奇,如果我们使用通过链表实现的存储桶,为什么存储桶排序的运行时间为O(n + k)。 例如,假设我们有以下输入:

n = no of element= 8

k = range = 3

array = 2,2,1,1,1,3,1,3

桶将如下所示:

1: 1 -> 1 -> 1 -> 1

2: 2 -> 2

3: 3 -> 3

假设我们将尾指针存储在链接列表中,则插入这些存储桶所花费的总时间为O(n)。

要删除,我们必须转到每个存储桶,然后删除该存储桶中的每个节点。 因此,当我们遍历每个链表时,复杂度应为O(K *桶链表的平均长度)。

但是,我读到存储桶排序的复杂度为O(n + k)。 为什么这与我的分析不一致? 请纠正我,因为我仍在学习计算复杂性。

"删除"是什么意思? 为什么在排序过程中需要删除?

我的意思是复制到原始Arary

为什么将存储桶实现为链接列表。 此列表中的所有元素都是相同的(即存储区索引),因此您只保留存储区中的项目数,而不保留每个元素。

请查看我的问题中的修改内容,即为什么我要这样实现

@Howard,具有相同键的项可能不会始终具有相同的元素标识,例如,如果哈希函数是h(x):x? x mod(256)

您的分析几乎是正确的,但是您缺少一个重要的细节。

现在,您是正确的,遍历输入数组以将元素分布到存储桶中需要时间O(n)。但是,当您说组装数组所需的总时间为O(k *(每个存储桶中的平均元素数))时,您的情况会稍微有些偏离。请注意,由于存在n个元素和k个存储桶,因此总运行时间为O(n),这将得出O(k *(n / k))= O(n)。要了解为什么真正的答案是O(n + k),我们需要更仔细地看一下big-O项。

对于初学者,您绝对正确,您在每个存储分区上花费的平均时间为O(n / k)。然后,您说由于有k个存储桶,因此总运行时间为O(k *(n / k))= O(n)。但是,这是不正确的:特别是k * O(n / k)= O(n)并非正确。其原因是,项O(n / k)隐藏了一个常数因子。当您访问每个存储桶并查看其中包含的元素时,它并不需要精确的n / k时间,甚至不需要n / k时间的某个常数倍。例如,如果存储桶为空会怎样?在那种情况下,您仍然要花一些时间在存储桶上,因为您必须确定不应迭代其元素。因此,每个存储桶所需时间的更准确表示类似于c 0 sub>(n / k)+ c 1 sub>,其中c 0 sub>和c 1 sub>是特定于实现的常量。该表达式当然是O(n / k)。

当您将此表达式乘以k以获取完成的工作总量时,就会发生问题。如果你计算

k * (c0(n / k) + c1)

你得到

c0n + c1k

如您所见,该表达式直接取决于k,因此总运行时间为O(n + k)。

获得此结果的更直接方法是查看存储桶排序第二步的代码,如下所示:

For each bucket b:

For each element x in b:

Append x to the array.

总体上需要完成多少工作?嗯,有k个不同的存储桶,因此最外面的循环至少需要O(k)时间,因为我们必须查看每个存储桶。在内部,内部循环将总共执行O(n)次,因为整个存储桶中共有n个元素。由此,我们得到O(n + k)的总运行时间。

这样做很重要的原因是,这意味着如果您尝试对数量众多的存储桶(例如,大于n)进行存储桶排序,则运行时可能会受到扫描所有存储桶以寻找所需时间的支配您实际使用的存储桶,即使其中大多数都是空的。基数排序之所以有用,是因为它使用了多个存储桶排序迭代,其中只有两个存储桶,它们的运行时间为O(n + 2)= O(n)。由于您只需要对此进行O(lg U)次迭代(其中U是数组中的最大值),因此运行时为O(n lg U)而不是从存储桶中获得的O(n + U)排序,这更糟。

希望这可以帮助!

我不明白如何logU迭代是数组中的最大值?

@ MrA-如果U是数组中的最大数字,则其中只有O(log U)位。 (考虑一下以10为基数的数字,其中N中的位数大约为log10 N)。 基数排序通过一次对一个数字进行排序而起作用,因此,数字中每个数字仅需要进行一次迭代,因此我们得到仅需要O(log U)迭代。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值