时间复杂度的计算

14天阅读挑战赛

时间复杂度的计算

    • 一、当代码为一层循环时
    • 二、当代码为二层循环时
    • 三、当代码为多层循环时

一、当代码为一层循环时

  1. 解题思路:
    a.列出循环次数k及每次循环变量的变化值
    b.找出每次循环变量与k的关系
    c.确定循环停止条件
    d.联立两式,解方程
    e.写结果
    例:
int i=0;
while(i*i*i<=n)
i++;

时间复杂度的计算_第1张图片

  1. 练习:

(1)

i=0;s=0while(s<n)
{ s=s+i;i++}

时间复杂度的计算_第2张图片

i=0;s=0while(s<n)
{ i++;s=s+i;}

时间复杂度的计算_第3张图片
(2)

i=n*n;
while(i!=1)
{ i=i/2;}

时间复杂度的计算_第4张图片

二、当代码为二层循环时

  1. 解题思路:
    a.列出外层循环中的变化值;
    b.列出内层语句的执行次数
    c.求和,写结果
    例:
int m=0,i,j;
for(i=1;i<=n;i++)
	for(j=1;j<=2*i;j++)
		m++;

时间复杂度的计算_第5张图片

  1. 练习:
    (1)
for(i=0;i<n;i++)
    for(j=0;j<m;j++)
        a[i][j]=0;

时间复杂度的计算_第6张图片
(2)

s = 0;
for(k=1;k<=n;k*=2)
	for(j=1;j<=n;j++)
		s++;

时间复杂度的计算_第7张图片

三、当代码为多层循环时

  1. 解题思路:
    第一种:抽象为计算三椎体积
    第二种:列式求和
    例:
for(i=0;i<=n;i++)
    for(j=0;j<=i;j++)
        for(k=0;k<j;k++)
            s++;

时间复杂度的计算_第8张图片时间复杂度的计算_第9张图片


在实际计算中,我们其实并不一定要计算精确的执行次数,只需要大概的执行次数,那么我们使用大O的渐进表示法去估算。
推导大O阶方法:

  1. 用常数1取代运行时间中所有加法常数
  2. 在修改后的运行次数执行函数中,只保留最高阶项
  3. 如果最高阶项存在且不是1,则去除与这个项目阶乘的常熟,得到的结果就是大O阶

例1

void Fun1(int N)
{
	int count =0;
	for(int k=0;k<100;k++)
	{
		++count;
	}
	printf("%d\n",count);
}
//fun1的时间复杂度为:O(1)		不是代表算法运行一次,是常数次

例2

const char* strchr(const char* str,int character);

等价于

while(*str)
{
	if(*str == character)
		return str;
	else
		++str;
}

则这个strchr的时间复杂度:O(N)

例3<冒泡排序的时间复杂度>

void BubbleSort(int* a,int n)
{
	assert(a);
	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;
	}
}

精确的值:F(N)=N*(N-1)/2
时间复杂度:O(N^2)

例4<二分查找>

int BinarySearch(int* a, int n, int x)
{
	assert(a);

	int begin = 0;
	int end = n;
	while (begin < end)
	{
		int mid = begin / ((end - begin) >> 1);
		if (a[mid] < x)
			begin = mid + 1;
		else if (a[mid] > x)
			end = mid;
		else
			return mid;
	}
	return -1;
}

则这个例子BinarySearch的时间复杂度为:O(log2 N)
在这里可以得出,算时间复杂度不能只去看是几层循环,而要去看它的思想
二分查找算法是非常牛逼的算法
N个数中查找

N个数中查找 大概查找次数
1000 10
100W 10
10亿 30

则在16亿人口中查找一个人,最多需要31次 <2^31约等于20亿>

例5<斐波那契>

long long Fac(size_t N)
{
	if (0 == N)
		return 1;

	return Fac(N - 1) * N;
}

则Fac的时间复杂度:O(N)
例6<斐波那契>

long long Fib(size_t N)
{
	if (N < 3)
		return 1;

	return Fib(N - 1) * Fib(N - 2);
}

则Fib的时间复杂度:O(2^N)
递归算法:递归次数*每次递归调用的次数
斐波那契数列的递归写法完全是一个实际中没用的算法,因为太慢了

你可能感兴趣的:(算法,C语言,算法,数据结构,c语言)