假设我们在Javascript中具有以下哈希映射类:
class myHash {
constructor() {
this.list = [];
}
hash(input) {
var checksum = 0;
for (var i = 0; i < input.length; i++) {
checksum += input.charCodeAt(i);
}
return checksum;
}
get(input) {
return (this.list[this.hash(input)]);
}
set(input, value) {
this.list[this.hash(input)] = value;
}
}
hash
函数具有一个循环,该循环的复杂度为O(n)
,并在获取和设置程序期间调用。这是否会使哈希映射O(n)
变得复杂?
答案 0 :(得分:4)
在执行Big-O分析时,您需要非常清楚变量是什么。通常, n 是不确定的或隐含的,但是了解确切的含义至关重要。
当 n 是唯一考虑的变量时,所有方法均为 O (1)。它们中没有一个在this.list
上循环,因此相对于哈希映射中的项目数,它们都在恒定时间中运行。
但是,您反对:hash()
中存在一个循环。 O (1)怎么可能。好吧,这是什么循环?它是否遍历地图中的其他项目?不会。它正在input
上循环,但是input.length
并不是我们正在考虑的变量。
当人们分析哈希映射性能时,他们通常会忽略传递的字符串的长度。如果这样做,那么 n 哈希映射性能相对于 O < / em>(1)。
如果您确实关心字符串的长度,则需要在分析中添加另一个变量。
哈希函数是 O ( k ),因为它在线性时间内遍历输入字符串。因此,get()
和set()
也是 O ( k )。
为什么我们通常不关心 k ?人们为什么只谈论 n ?这是因为 k 是分析哈希函数性能的一个因素,但是当我们分析哈希映射的性能时,我们并不真正在乎哈希函数的运行速度。我们想知道哈希图本身的性能如何,并且 k 都不会直接影响它的代码。只有hash()
是,hash()
不是哈希映射的一部分,它只是它的输入。