📜  算法中的常数和线性空间复杂度

📅  最后修改于: 2021-10-23 05:27:26             🧑  作者: Mango

作为一名程序员,您可能已经解决了很多编程挑战。在编程空间中,当我们需要执行程序时,时间复杂度很重要。我们的算法应该是高效的,而且应该花费更少的时间。每当您为程序编写解决方案时,都需要一些内存来完成,这对我们的程序占用较少内存并在给定时间范围内执行很重要。

恒定线性空间算法复杂度

对于任何程序,内存可用于以下用途……

  1. 变量(包括常量值、临时值)
  2. 程序说明
  3. 执行

空间复杂度是算法执行和产生结果所需的内存总量。很多时候程序员对辅助空间空间复杂度感到困惑两者是不同的。在任何算法中,我们使用的额外空间或临时空间称为辅助空间。

Space Complexity = Auxiliary Space + Input space

在本文中,我们将了解执行时的内存使用情况,并了解空间复杂度的分类。该算法使用内存空间有以下三个原因……

1. 指令空间:在编写算法时,指令的编译版本需要一定量的内存,称为指令空间。

2.环境栈:需要存储恢复挂起的函数所需的环境信息。当一个算法在另一个算法中被调用时使用。在这些情况下,我们将当前变量推入系统堆栈,在那里等待进一步执行。之后,我们在算法内部调用它

让我们以两个函数为例。函数X() 和函数Y()。函数X() 的变量将临时存储在系统堆栈中,而函数Y() 在函数X() 内部调用和执行。

3. 数据空间:在程序执行期间,存储常量和变量值所需的任何空间都被视为数据空间。

注意:在编写算法时,您只需要考虑数据空间。您不需要计算指令空间环境堆栈

现在让我们了解空间复杂度的分类。空间复杂度可以通过两种方式计算。这取决于程序。程序可以是常数程序或线性程序。

如何计算空间复杂度?

在算法中,首先需要计算内存总量来评估空间复杂度。您需要知道不同类型数据类型的变量所使用的内存值。适用于不同的操作系统或不同的机器。每个机器的这个值可能不同,但方法保持不变。

让我们举一个计算空间复杂度的例子……

{
   int x = a * b * c;
   return(x);
}

在上面的表达式中,a、b、c 和 x 都是整数类型。它们每个占用 4 个字节。现在我们可以计算总内存。这将会…

(4(4) + 4) = 20 字节。额外的 4 个字节用于返回值。在这里,我们需要为所有输入提供固定数量的内存。所以这种类型的复杂性称为恒定空间复杂性

让我们转向另一个例子……

// n is the length of array a[]
int sum(int arr[], int n)
{
int sum = 0;  // 4 bytes for sum
for(int i = 0; i < n; i++) // 4 bytes for i
{  
    sum  = sum + arr[i];  
}
return(sum);
}
  • 在上面的例子中,我们需要为数组的每个元素分配 4*n 字节的空间。
  • 和、n、i 和返回值各占 4 个字节。

所以内存总量将是 (4n+12),随着输入值 n 的增加而线性增加。这称为线性空间复杂度。如果您有一个循环变量 I,那么所需的空间复杂度将为 1 个字。

如果您已经从上面的示例中理解了计算空间复杂度的概念,那么随着算法复杂度的增加,您可以按照类似的方法计算二次和其他空间复杂度。始终尝试最小化算法的空间复杂度。更少的空间使您的算法更好、更高效。

概括

  • O(1) 复杂度:当程序不包含任何循环、递归函数或对任何其他函数的调用时,我们考虑恒定空间复杂度。
  • O(n) 复杂度:当程序包含任何循环时,我们考虑线性空间复杂度。

算法的空间复杂度备忘单

  • 冒泡排序: O(1)
  • 选择排序: O(1)
  • 插入排序: O(1)
  • 归并排序: O(n)
  • 快速排序: O(n)
  • 堆排序: O(1)
  • 基数排序: O(n+k) 其中 k — 数组元素的范围。

最后的想法

空间复杂度在决定算法的效率方面起着至关重要的作用。始终尝试实现一种花费更少时间的算法。如果程序占用大量内存空间,编译器将不会让您运行它。永远记住下面的空间复杂度公式

Space Complexity = Auxiliary space + Space use by input values