算法:复杂度

简介: 算法:复杂度

数据结构

数据结构是计算机存储,组织数据的方式,指相互之间存在一种或多种特定关系的数据元素的集合

数据结构与数据库的对比

数据库:在磁盘上管理数据,对数据进行增删查改

数据结构:在内存上管理数据,对数据进行增删查改


算法

算法可以简单理解为解决问题的方法,在编写程序的时候,我们会遇到各种各样的问题,也会想出各种各样的解决办法,但有的办法会消耗大量的cpu算力或占用大量内存, 因此可以用时间复杂度以及空间复杂度来判断一个算法的优劣


时间复杂度

算法的时间复杂度并不是说电脑通过该算法解决问题所消耗的时间,因为不同配置的电脑的cpu算力差距不小,同一个程序在不同电脑上消耗的时间都会不同,这样是无法评定该算法的优劣的。 既然不同电脑处理一个程序所消耗的时间不同,那么处理程序内的一个指令的时间几乎是相等的,因为现在pc算力基本都能达到上亿次每秒,处理一个指令的时间都微乎其微,可以认为相等,这样,我们在评测一个算法的优劣可以通过计算大致要处理指令的个数


表示算法的时间复杂度用大O渐进法表示

推导大O阶方法:

1、用常数1取代运行时间中的所有加法常数。

2、在修改后的运行次数函数中,只保留最高阶项。

3、如果最高阶项存在且不是1,则去除与这个项目相乘的常数。得到的结果就是大O阶

常见的复杂度有O(1), O(log), O(n), O(nlog), O(n^2), O(2^n), O(n!)

logN,lgN 在程序的算法复杂度中默认都是log2^n

需要注意的是,复杂度往往是取最坏的结果

int test()
{
  int counter = 0;
  for (int i = 0; i < 10000000000; i++)
  {
    counter++;
  }
  return counter;
}
//可能会有同学认为上面的时间复杂度应该是O(n),但结果并非如此
上面的数字尽管很大,但它仍然是一个常数,以cpu的算力来说,它的复杂度就是O(1)
int test(int n)
{
  int counter = 0;
  for (int i = 0; i < n; i++)
  {
    counter++;
  }
  return counter;
}
//上面的代码的时间复杂度是O(n),n的数值并不确定有多大,以最坏的结果为准
int test(int n, int m)
{
  int counter = 0;
  for (int i = 0; i < n; i++)
  {
    counter++;
  }
  for (int i = 0; i < m; i++)
  {
    counter++;
  }
  return counter;
}
//上面代码的时间复杂度是O(m+n)

时间复杂度的推导靠得是算法的思想,不能看到循环就默认其复杂度就是O(n),这样偷懒的想法是不可取的。


空间复杂度

空间复杂度指的是一个算法在运行过程中临时占用存储空间大小的亮度,空间复杂度并不是整个程序在运行时占用了多少字节的空间,而是在运行过程中创建的临时变量的个数。需要注意的是函数运行时所需要的栈空间(存储参数、局部变量、一些寄存器信息等)在编译期间已经确定好了,空间复杂度是在程序跑起来之后额外向内存申请的空间。

空间复杂度同样是用大O渐进法表示

void BubbleSort(int* a, int n)
{
   for (size_t end = n; end > 0; --end)
   {
      int exchange = 0;
      for (size_t i = 1; i < end; ++i)
      {
         if (a[i-1] > a[i])
         {
            Swap(&a[i-1], &a[i]);
            exchange = 1;
         }
      }
      if (exchange == 0)
       break;
   }
}
//冒泡排序的空间复杂度是O(1),排序的数组是主程序传过来的,并不是冒泡函数临时申请的,控制循环的两个变量及exchange变量虽然是临时申请的,但过了作用域的块之后就被销毁了,本质上是没有累积创建的,因此该程序只申请了3个变量,是常数个
long long* Fibonacci(size_t n)
{
   if(n==0)
   return NULL;
   long long * fibArray = (long long *)malloc((n+1) * sizeof(long long));
   fibArray[0] = 0;
   fibArray[1] = 1;
   for (int i = 2; i <= n ; ++i)
   {
     fibArray[i] = fibArray[i - 1] + fibArray [i - 2];
   }
   return fibArray;
}
//该例的空间复杂度为O(n),因为开辟了n+1个额外的空间
long long Fib(size_t N)
{
   if(N < 3)
   return 1;
   return Fib(N-1) + Fib(N-2);
}
//该函数的空间复杂度为O(n),因为开辟了n个数量级的函数栈,因为函数栈帧调用完就释放,最多累计调用n个函数栈帧

目录
相关文章
|
6月前
|
机器学习/深度学习 存储 算法
【算法与数据结构】复杂度深度解析(超详解)
【算法与数据结构】复杂度深度解析(超详解)
【算法与数据结构】复杂度深度解析(超详解)
|
6月前
|
存储 算法
数据结构与算法:复杂度
数据结构: 数据结构是用于存储和组织数据的方式,以便可以有效地访问和修改数据。不同的数据结构适用于不同类型的应用,并且具体的数据结构可以大幅影响程序的性能。数据结构分为两大类:线性数据结构和非线性数据结构。 算法: 算法是完成特定任务的一系列操作步骤,是解决问题的明确规范。算法的效率通常通过时间复杂度和空间复杂度来评估,即算法执行所需的时间和空间资源。
|
6月前
|
机器学习/深度学习 存储 算法
如何评判算法好坏?复杂度深度解析
如何评判算法好坏?复杂度深度解析
110 0
|
5月前
|
机器学习/深度学习 存储 算法
1 .算法的复杂度(超全)
1 .算法的复杂度(超全)
|
30天前
|
移动开发 算法 前端开发
前端常用算法全解:特征梳理、复杂度比较、分类解读与示例展示
前端常用算法全解:特征梳理、复杂度比较、分类解读与示例展示
21 0
|
2月前
|
算法 搜索推荐 开发者
别再让复杂度拖你后腿!Python 算法设计与分析实战,教你如何精准评估与优化!
在 Python 编程中,算法的性能至关重要。本文将带您深入了解算法复杂度的概念,包括时间复杂度和空间复杂度。通过具体的例子,如冒泡排序算法 (`O(n^2)` 时间复杂度,`O(1)` 空间复杂度),我们将展示如何评估算法的性能。同时,我们还会介绍如何优化算法,例如使用 Python 的内置函数 `max` 来提高查找最大值的效率,或利用哈希表将查找时间从 `O(n)` 降至 `O(1)`。此外,还将介绍使用 `timeit` 模块等工具来评估算法性能的方法。通过不断实践,您将能更高效地优化 Python 程序。
54 4
|
2月前
|
算法 程序员 Python
程序员必看!Python复杂度分析全攻略,让你的算法设计既快又省内存!
在编程领域,Python以简洁的语法和强大的库支持成为众多程序员的首选语言。然而,性能优化仍是挑战。本文将带你深入了解Python算法的复杂度分析,从时间与空间复杂度入手,分享四大最佳实践:选择合适算法、优化实现、利用Python特性减少空间消耗及定期评估调整,助你写出高效且节省内存的代码,轻松应对各种编程挑战。
41 1
|
3月前
|
算法
【初阶数据结构】复杂度算法题篇
该方法基于如下的事实:当我们将数组的元素向右移动 k 次后,尾部 kmodn 个元素会移动至数组头部,其余元素向后移动 kmodn 个位置。
26 1
|
4月前
|
机器学习/深度学习 存储 算法
【数据结构】算法的复杂度
算法的时间复杂度和空间复杂度
72 1
【数据结构】算法的复杂度