为什么二分查找算法中的赋值不会增加时间复杂度?

时间:2018-07-07 03:25:48

标签: algorithm sorting time-complexity big-o binary-search

对于插入排序,如果存在一组 n 个递减元素,则情况更糟。 比较所有元素从左到右的总时间为:

1 + 2 + ... +(n-2)+(n-1)

在计算时间复杂度时还考虑的是交换这些元素,这也是:

1 + 2 + ... +(n-2)+(n-1)

最终,我们得出O(n ^ 2)。

采用另一种算法,例如二进制搜索; 找到中点的动作,然后将其与该中点进行比较,然后在列表的每个分区中将中点重新分配给highlow一半的时间根本不算时间复杂度。仅将中点与目标值进行比较的操作。 那么为什么经典的排序算法(三个赋值语句)中的交换会影响时间复杂性,而二进制搜索中的中点赋值却没有呢?


更新

Taylor Edmiston指出

  在二进制排序中,在树结构中查找比在数据结构为数组/列表的插入排序中便宜。插入排序的病理情况是,每个元素都必须交换过去列表中已经存在的所有其他元素。

但是“交换”是否真的只是三个变量分配?

if (a[i] > a[j])
   x = a[i];    
   a[i] = a[j];    
   a[j] = x; 

与一般的二进制搜索算法中看到的以下情况相比,这三种分配如何占主导地位?

while(low < high)
   mid = (low + high) / 2;    // assignment 1
   if (data[mid] == target) 
      return true;
   if (data[mid] < testValue)
      low = mid + 1;          // assignment 2_a
   else
      high = mid;             // assignment 2_b

2 个答案:

答案 0 :(得分:1)

他们做到了!

在插入排序中,您执行O(n²)比较和O(n²)分配,但总数仍为O(n²)。

在二进制搜索中,您执行O(Log n)比较和O(Log n)分配,但总数仍为O(Log n)。

但是,通常的做法是,当您知道某项操作是按另一种操作进行的(例如,在二进制搜索中,每个比较执行一次赋值)时,只计算一种类型的操作。

顺便说一句,请考虑还有其他未考虑的操作,例如数组取消引用或循环语句。只要使用的操作数保持成比例(或较低的数量级),就可以使用big-Oh表示法。


其他示例:

一个人可以通过二分查找和交换来实现插入排序。

在这样的版本中,您将执行大约

Log 1 + Log 2 + Log 3 + Log n-1比较,即O(n Log n),

,仍然是O(n²)交换。在全球范围内,算法行为为O(n²)。

在复杂性分析中,您可以省去对比较进行计数,因为它们以较低的数量级起作用,并且只关心分配。 提供了这种不平衡状态

答案 1 :(得分:-1)

没有一种一致的时间复杂度度量方法。

对于排序算法,基本操作被视为比较(仅此而已)。哈希表操作也是如此-它计算完成的比较次数。最好将“ mergesort的时间复杂度为O(n log n)”表示“ mergesort进行O(n log n)比较”。最好将“哈希表查找平均为O(1)”理解为“哈希表查找平均执行O(1)比较”。

这是使事情保持简单的必要条件-例如,如果对字符串数组进行排序,则字符串比较在基本操作中不是O(1)-开销取决于字符串的长度。如果您尝试忽略此问题并说“假设我们的计算机可以在O(1)中执行比较”,则会发现排序算法可以执行少于n log n个基本操作。我有一个(rather technical) blog post about this,其中包括对(甚至更具技术性的)文献的一些引用。

在考虑其他算法时,您可以测量基本运算(例如,赋值,算术运算等)。即使这样,有时您仍可能会认为算术运算的成本是恒定的,或者取决于操作数的大小。

几乎所有偶然性复杂度理论的使用都忽略了“时间”的含义上的差异,人们将很高兴地使用不同的时间概念来组合和比较不同的分析。这在实践中效果很好,并给出了有用的结果,但从理论上讲并不合理。