基数排序赋值部分的运行时
Posted
技术标签:
【中文标题】基数排序赋值部分的运行时【英文标题】:Runtime for Assignment Part of Radix Sort 【发布时间】:2021-06-27 20:20:19 【问题描述】:您如何描述以下代码的运行时分析?这是基数排序的第二步(第一步是创建计数器)。
const reAssignArraySlots = (arr, counter) =>
let i = 0;
let j = 0;
while(i<arr.length)
let k = 0;
let num = counter[i] || 0;
while(k<num)
arr[j] = i;
k+=1;
j+=1;
i+=1;
j+=1;
return arr;
;
我相信无论如何都会是 O(n),但我想检查一下这种直觉。例子:
A) 所有元素都是相同的。计数器将是 '2': 3 。带有 i 的 while 循环将处理 1x,带有 k 的 while 循环将处理 3x,并且每次插入都是 O(1)。我将 3 次插入相加得到 O(3),即 O(n)
B) 所有元素都是独一无二的。计数器将是 '2': 1, '1': 1, '3': 1 。 while 循环将处理 i 3x。每次插入都是 O(1),加起来是 O(3),即 O(n)。
C) 非唯一的、非连续的元素。 '4':1,'1':1,'3':2。在这里我不确定。每次插入都会有 O(1),但我们会额外检查 i = 2,这不在此处。不确定这是否会使我们达到 O(4)。最终,如果我们有足够稀疏的东西,这可能会得到 O(n^2)。
代码的其余部分:
const getCounter = (arr) =>
const counter = ;
let min, max;
arr.forEach((item) =>
if(counter[item] !== undefined)
counter[item] += 1;
else
counter[item] = 1;
);
return counter;
;
export const countSort = (arr) =>
const counter = getCounter(arr);
return reAssignArraySlots(arr, counter);
;
【问题讨论】:
【参考方案1】:我看到 2 个嵌套循环,所以我倾向于说它不比 O(n^2) 慢。
i
在外循环中递增
k
在内部循环中递增(并在循环之前设置为零)
j
在两个循环中都会递增
k
对于每个循环可能会有所不同,但可以说有一个平均值 ave_k
在循环结束时,在我看来j
将始终等于i * ave_k
。
最大的问题是k
(或ave_k
)的大小是多少?
i
成正比吗?那么你就有了 O(n^2)。
与ln(i)
成正比吗?那么你就有了 O(n ln(n) )。
它是恒定的,独立于i
吗?那么你就有了 O(n)。
它通常是i
的平方吗?那么你就有了 O(n^2)
它通常是i
的平方根吗?然后你有 O(n sqrt(n) )
【讨论】:
以上是关于基数排序赋值部分的运行时的主要内容,如果未能解决你的问题,请参考以下文章