1、概念
时间复杂度之大O渐进表示法
定义:一个算法语句总的执行次数是关于问题规模N的某个函数,记为f(N),N称为问题的规模。语句总的执行次数记为T(N),当N不断变化时,T(N)也在变化,算法执行次数的增长和f(N)的增长速率相同。则有T(N)=O(f(N)),称O(f(N))为时间复杂度的O渐进表示法。
2、常见时间复杂度
计算以下函数语句总执行次数与问题规模n的函数表达式:即时间复杂度
1、
void Test0(int n)
{
int icount = 0;
for(int i=0; i<10; i++)
{
icount++;
}
}
总执行次数:f(N) = 10
时间复杂度的O渐进表示法O(f(N)) = O(1)
2、
void Test1(int m,int n)
{
int icount = 0;
for(int i=0; i<m; i++)
{
icount++:
}
for(int j=0; j<n; j++)
{
icount++;
}
}
总执行次数f(N) = m + n
O(f(N)) = O(1)
3、
void Test2(int n)
{
int icount = 0;
for(int i=0; i<10; ++i)
{
icount++;
}
for(int i=0; i<2*n; ++i)
{
icount++;
}
for(int i=0; i<n; ++i)
{
for(int j=0; j<n; ++j)
{
icount++;
}
}
}
总执行次数:f(N) = n^2+2n+10
O(f(N)) = O(n^2)
一般算法O(n)计算方法:
- 用常数1取代运行时间中的所有加法常数
- 在修改后的运行次数函数中,只保留最高阶项
- 如果最高阶项系数存在且不是1,则去除与这个项相乘的常数
3、分治法的时间复杂度
二分查找
#include <stdio.h>
int binary_search(int *arr,int sz,int k)
{
int left = 0;
int right = sz-1; //注意这里的减1问题
int mid = 0;
while(left <= right) //注意这里的等号问题
{
mid = left+((right-left)>>1);
if(arr[mid] == k)
{
return mid;
}
else if(arr[mid]>k)
{
right = mid-1;
}
else
{
left = mid+1;
}
}
return -1;
}
int main()
{
int k = 4;
int arr[] = {1,2,3,4,5,6,7,8,9};
int size = sizeof(arr)/sizeof(arr[0]);
int ret = binary_search(arr,size,k);
if(ret == -1)
printf("没有找到!\n");
else
printf("找到了,下标是%d",ret);
}
二分查找的解析
一列有序的数中查找4
right指向最后一个元素
如果right指向9的下一个元素的位置,将代码
int right = sz - 1;//改为
int right = sz;
while(left <= right)//改为
while(left < right)
right = mid -1;//改为
right = mid;