深入理解算法时间复杂度

算法时间复杂度:事前预估算法时间开销T(n)与问题规模n的关系(T表示“time”)

算法一:逐步递增型

void Loveyou(int n)//n为问题规模
{
  int i=1;//1
  while(i<=n)//2
  {
    i++;//3
    printf("I love you %d\n",i);//4
  }
  printf("I love you more than %d\n",n);//5
}
int main()
{
  Loveyou(3000);
  return 0;
}

语句频度:

1.  1次

2.  3001次

3.4  3000次

5. 1次

T(3000)=1+3001+3000*2+1

时间开销与问题规模n的关系:

T(n)=3n+3

  • 问题一:是否可以简化表达式?

当n足够大时

T(n)=3n+3

T(n)=n2+3n+1000

T(n)=n3+3n+100 

以上的式子可以直接保留对T(n)影响最大的一项

  • 加法规则:多项相加,只保留最高阶的项,且系数变为1
  • 乘法规则:多项式相乘都保留

数量级比较:

O(1)<O(log2n)<O(n)<O(nlog2n)<O(n2)<O(n3)<O(2n)<O(n!)<O(nn)

以上的比较原理是可以根据洛必达法则比较出来的

  • 问题二:如果有上千行代码也需要一行一行数吗?

结论1:顺序执行的代码只会影响常数项,可以忽略

结论2:只需挑循环中一个基本操作分析它的执行次数与n的关系即可

算法二:嵌套循环型

void Loveyou(int n)
{
  int i=1;
  while(i<=n)
  {
    i++;
    printf("I love you %d\n",i);
    for(int j=1;j<=n;j++)
    {
      printf("I am man\n");
    }
  }
  printf("I love you more than %d\n",n);
}

时间开销与问题规模n的关系:T(n)=O(n)+O(n2)=O(n2)

结论3:如果有多层循环,只需要关注最深层循环循环了多少次

算法三:指数递增型

void Loveyou(int n)
{
  int i=1;
  while(i<=n)
  {
    i=i*2;
    printf("I love you %d\n",i);
  }
  printf("I love you more than\n");
}

计算上诉算法的时间复杂度T(n);

解答:设最深层循环的语句频度(总共循环的次数)为x,则由循环条件可知,循环结束时刚好满足:2x>n  x=log2n+1,T(n)=O(x)=O(log2n)

算法四:搜索数字型

void Loveyou(int flag[],int n)
{
  printf("I an iron man\n");
  for(int i=0;i<n;i++)
  {
    if(flag[i]==n)
    {
      printf("I love you %d\n",n);
      break;
    }
  }
}

最好情况:元素n在第一个位置---O(1)

最坏情况:元素n在最后一个位置---O(n)

平均情况:假设元素n在任意一个位置的概率相同 为:1/n---O(n)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

写不出bug的小李

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值