当前位置:首页 > C++目录 > 正文内容

如何估算时间复杂度

亿万年的星光5年前 (2021-08-19)C++目录2139

首先:

  常见的算法时间复杂度由小到大依次为:Ο(1)<Ο(log2n)<Ο(n)<Ο(nlog2n)<Ο(n^2)<Ο(n^3)<…<Ο(2^n)<Ο(n!)

时间复杂度可以简单理解为最多执行次数。


一、O(1)

一般情况下没有其他循环和递归调用,时间复杂度一般都是O(1)。比如下面这样的代码

#include<iostream>
using namespace std;
int main(){
	int a=0,b=0,x=0,y=0;
	cin>>a>>b;
	x=a+b;
	y=a-b;
	if(x>y){
	 cout<<x;
	}else{
	 cout<<y;
	}
	return 0;
}

二、O(n)

一般情况下,一个循环的时间复杂度是O(n),多个循环并列也是取循环次数最多的那个作为时间复杂度。当数据量增大n倍,耗时增大n倍。

#include<iostream>
using namespace std;
int main(){
	int a=n;
	cin>>n;
	for(int i=0;i<n;i++){
	    cout<<i;
	}
	return 0;
}


三、O(n2)、O(n*m)

双重循环嵌套一般就是O(n2)。当数据量增大n倍,耗时增大n方倍。

#include<iostream>
using namespace std;
int main(){
	int n=0;
	cin>>n;
	for(int i=0;i<n;i++){
	    for(int j=0;j<n;j++){
	        cout<<i;
	    }
	}
	return 0;
}

如果循环嵌套外层循环是n,内层循环是m。

#include<iostream>
using namespace std;
int main(){
	int n=0,m=0;
	cin>>n>>m;
	for(int i=0;i<n;i++){
	    for(int j=0;j<m;j++){
	        cout<<i;
	    }
	}
	return 0;
}

这个时候的时间复杂度是O(n*m)。


四、O(logn)

当数据增大n倍时,耗时增大logn倍。

#include<iostream>
using namespace std;
int main(){
	int n=0;
	cin>>n;
	for(int i=0;i<n;i++){
	   i*=2;
	   cout<<i;
	}
	return 0;
}

本来循环次数是n,现在i*=2了。那么答案是log(2)(n)。

反着想也可以,原来循环n次,现在每次i变成原来的2倍,也就是2的k次方等于n。那么正好就是log(2)(n),即O(log n)


或者下面这样:

#include<iostream>using namespace std;
int main(){
int n=0;
cin>>n;
while((n=n/2)>0){
    cout<<n;
}
 return 0;
}

时间复杂度也是O(logn)


五、O(nlogn)

一般归并排序和堆排序是O(nlogn)。 

常见的是外层循环的时间复杂度是n,内层循环的时间复杂度是logn。

比如下面这样:

for(int i=1; i<=n; i++)
{
	for(int j=1; j<=n; j+=i)
	{
		.....   //复杂度为O(1);
	}
}

注意:外层循环是n,内层循环j每次都增加i。

常见算法的时间复杂度

数据结构时间复杂度最坏情况下的辅助空间复杂度
  最佳平均最差最差
快速排序数组O(n log(n))O(n log(n))O(n^2)O(n)
归并排序数组O(n log(n))O(n log(n))O(n log(n))O(n)
堆排序数组O(n log(n))O(n log(n))O(n log(n))O(1)
冒泡排序数组O(n)O(n^2)O(n^2)O(1)
插入排序数组O(n)O(n^2)O(n^2)O(1)
选择排序数组O(n^2)O(n^2)O(n^2)O(1)
桶排序数组O(n+k)O(n+k)O(n^2)O(nk)
基数排序数组O(nk)O(nk)O(nk)O(n+k)


算法数据结构时间复杂度空间复杂度
  平均最差最差

深度优先搜索 (DFS)Graph of |V| vertices and |E| edges-O(|E| + |V|)O(|V|)

广度优先搜索 (BFS)Graph of |V| vertices and |E| edges-O(|E| + |V|)O(|V|)

二分查找Sorted array of n elementsO(log(n))O(log(n))O(1)

穷举查找ArrayO(n)O(n)O(1)

最短路径-Dijkstra,用小根堆作为优先队列Graph with |V| vertices and |E| edgesO((|V| + |E|) log |V|)O((|V| + |E|) log |V|)O(|V|)

最短路径-Dijkstra,用无序数组作为优先队列Graph with |V| vertices and |E| edgesO(|V|^2)O(|V|^2)O(|V|)

最短路径-Bellman-FordGraph with |V| vertices and |E| edgesO(|V||E|)O(|V||E|)O(|V|)



据结构时间复杂度空间复杂度
 平均最差最差
 索引查找插入删除索引查找插入删除 
基本数组O(1)O(n)--O(1)O(n)--O(n)
动态数组O(1)O(n)O(n)O(n)O(1)O(n)O(n)O(n)O(n)
单链表O(n)O(n)O(1)O(1)O(n)O(n)O(1)O(1)O(n)
双链表O(n)O(n)O(1)O(1)O(n)O(n)O(1)O(1)O(n)
跳表O(log(n))O(log(n))O(log(n))O(log(n))O(n)O(n)O(n)O(n)O(n log(n))
哈希表-O(1)O(1)O(1)-O(n)O(n)O(n)O(n)
二叉搜索树O(log(n))O(log(n))O(log(n))O(log(n))O(n)O(n)O(n)O(n)O(n)
笛卡尔树-O(log(n))O(log(n))O(log(n))-O(n)O(n)O(n)O(n)
B-树O(log(n))O(log(n))O(log(n))O(log(n))O(log(n))O(log(n))O(log(n))O(log(n))O(n)
红黑树O(log(n))O(log(n))O(log(n))O(log(n))O(log(n))O(log(n))O(log(n))O(log(n))O(n)
伸展树-O(log(n))O(log(n))O(log(n))-O(log(n))O(log(n))O(log(n))O(n)
AVL 树O(log(n))O(log(n))O(log(n))O(log(n))O(log(n))O(log(n))O(log(n))O(log(n))O(n)


    扫描二维码推送至手机访问。

    版权声明:本文由青少年编程知识记录发布,如需转载请注明出处。

    分享给朋友:

    相关文章

    最小生成树—Prim(普里姆)算法

    最小生成树—Prim(普里姆)算法

    一、算法概述Prim 算法是一种用于求解加权无向连通图的最小生成树(MST) 的贪心算法。它从一个顶点开始,逐步扩展生成树,每次选择连接已选顶点集和未选顶点集的最小权重边。二、算法思想初始化:从任意顶...

    如何计算一个程序的运行时间(防止超时)

    再一些OJ系统中,做题的时候常常会超时,但是很多人不知道自己的程序是否会超时,不知道如何检查自己的程序。这篇文章主要介绍几种监测自己程序运行时间的程序。头文件<time.h> ...

    【数据结构】栈的基本操作

    0.前言上一篇中简单介绍了栈的定义,这一篇中介绍栈的基本用法,包含压栈,出栈,判断栈空,判断栈中元素个数等。下面进行详细介绍1.基本用法本文介绍的栈的主要操作,使用栈之前加入<stack>...

    编写第一个C++程序

    编写第一个C++程序

    前面的文章介绍了Dev-C++的下载安装:【入门篇】>>> DEVC++下载、安装、简单使用 - 青少年编程知识记录 (codecoming.com)今天讲一下如何使用Dev-C++...

    图的访问与遍历-深度优先搜索

    图的访问与遍历-深度优先搜索

    一、图的遍历图的遍历是指从图中的某个顶点出发,按照一定规则访问图中所有顶点且每个顶点仅访问一次的过程,核心分为深度优先搜索(DFS) 和广度优先搜索(BFS) 两大类,适用于无向图...

    【数论】同余定理与同余方程

    定义同余定理是数论中的一个重要概念。它的定义是这样的:给定一个整数m,如果两个整数a和b满足(a-b)能够被m整除,即(a-b)/m 得到一个整数,那么就成整数a和b对模m同余,记作a≡b(mod m...