提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
对于判断一段代码的好坏,取决于该代码运行的时间与占用的空间,也就是时间复杂度与空间复杂度,本章就先讲一下时间复杂度,主要包含常见的时间复杂度的计算。
时间复杂度是衡量算法运行效率的一个重要指标,它表示随着输入规模的增长,算法执行时间的增长趋势。以下是关于时间复杂度的计算方法与常见的时间复杂度:
1.常数阶O(1)
无论输入规模如何变化,算法执行的时间都是一个常数。例如,直接访问数组中的一个元素,时间复杂度为
O(1)。
总的来说:代码中只是进行了简单的加法运算,不随输入规模变化,执行时间恒定。
注意:简单说一下哈希表也是O(1)。
int add(int x,int y)
{
return a+b;
}
2.对数阶 O(log n):
算法的执行时间与输入规模的对数成正比。常见于二分查找等算法,每次操作都能将问题规模缩小一半。
例如 二分查找
int towfen(int x,int low,int high)
{
while(low<high)
{
int m=low+(high-low)/2;
if(a[m]==x)return 1;
else if(a[m]>x)
{
high=m;
}
else
{
low=m+1;
}
}
return 0;
}
其主要思想就是折半查找,假设有个数组{1,2,3,4,5,6,7,8,9}
要查找的元素为3,则此时的m=5,而3小于当下标为5时的数,以此只需要查找一半,每次都减少一半,直到最后找到。
3.线性阶 O(n)
算法的执行时间与输入规模 n 成正比。如上述示例中对列表元素进行求和的操作,时间复杂度为 O(n)。
简单举例
int sum(int n)
{
int s=0;
for(int i=1;i<=n;i++)
s+=i;//一共循环了n次
return s;
}
4.线性对数阶 O(nlog n)
通常出现在一些分治算法中,如归并排序、快速排序等。这类算法将问题分成多个子问题,每个子问题的规模是原问题的一部分,然后对这些子问题分别进行处理。
就以快排的例子来说:
void quike_sort(int low,int high)
{
if(low>=high)
return ;
int mid=rand()%(high-low)+low;//随机取个中间数
int l=low,i;
int x1=0,x2=0,x3=0;
for(i=low;i<high;i++)
{
if(a[i]>a[mid])//大于所取的数存入b数组
{
b[x1++]=a[i];
}
else if(a[i]==a[mid])//把等于所取的数放入c数组
{
c[x2++]=a[i];
}
else//把小于所取的数放入d数组
{
d[x3++]=a[i];
}
}
for(i=0;i<x3;i++)
{
a[l++]=d[i];
}
for(i=0;i<x2;i++)
{
a[l++]=c[i];
}
for(i=0;i<x1;i++)
{
a[l++]=b[i];
}//对其进行合并
quike_sort(low,low+x3);//再次进入递归将左边的数组排好顺序
quike_sort(low+x3+x2,high);//同理排序右边数组
}
5.平方阶 O(n^2):
常见于一些嵌套循环的算法中。例如,冒泡排序、选择排序等,它们需要对数据进行多次遍历和比较,时间复杂度为 O(n^2)。
代码如下
void qsort(ll n)
{
ll m[n];
for(int i=0;i<n;i++)
cin>>m[i];
for(int i=0;i<n;i++)
for(int j=i+1;j<n;j++)
{
if(m[i]>m[j])
{
int t=m[i];
m[i]=m[j];
m[j]=t;
}
}
}
6.立方阶 O(n^3)
一般出现在三层嵌套循环的算法中。例如,计算两个 n*n 矩阵的乘法,时间复杂度为 O(n^3)。
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
cout<<"1"<<endl;
7.指数阶 O(2^n)
当算法的时间复杂度为指数阶时,随着输入规模 n 的增加,算法的执行时间会呈指数级增长。例如,计算斐波那契数列的递归算法,时间复杂度为 O(2^n),这种算法在实际应用中效率较低,只适用于小规模问题。
#include
// 递归函数计算斐波那契数列的第 n 项
int fibonacci(int n) {
if (n <= 1) {
return n;
}
return fibonacci(n - 1) + fibonacci(n - 2);
}
该递归算法的时间复杂度是 (O(2^n)),因为在每一步递归中,问题会被分解成两个子问题,并且没有对重复子问题进行优化,所以时间复杂度会呈指数级增长。
总而言之,该篇文章就是简单的介绍了一下时间复杂度,仅仅是自己的粗鄙的看法,本人也是第一次接触这些东西,就想着发一篇文章来加深一下自己的理解,新人小白一枚,大佬勿喷,有理解错的地方希望能给小弟提点一下