马上加入IBC程序猿 各种源码随意下,各种教程随便看! 注册 每日签到 加入编程讨论群

C#教程 ASP.NET教程 C#视频教程程序源码享受不尽 C#技术求助 ASP.NET技术求助

【源码下载】 社群合作 申请版主 程序开发 【远程协助】 每天乐一乐 每日签到 【承接外包项目】 面试-葵花宝典下载

官方一群:

官方二群:

算法时间复杂度计算

  [复制链接]
查看5109 | 回复5 | 2018-9-12 16:37:51 | 显示全部楼层 |阅读模式
本帖最后由 剑弑 于 2018-9-26 23:13 编辑

       算法!!!算法相信每一个软件工程师(程序员)都或多或少的接触的到,有时候甚至要自己去写。虽然写一个算法并不难,只要做到能够对一定规范的输入,在有限的时间内获得要求的结果输出就行;但我们所写的算法是否是最优最好的呢?我们该怎么去判断算法的好坏呢?当我们有好几种算法的实现该如何去选择最优的算法呢?时间复杂度!我相信很多都能答上来。对,就是时间复杂度!!!!!
      我们都知道每一个算法都有它自己的时间复杂度,但这个时间复杂度该怎么去计算呢?计算算法的时间复杂度就是我今天要跟大家分享的,也希望有对时间复杂度了解更深的大神指出我的不足。
      不同规模的输入需要的基本操作数是不相同的,如:一个排序算法排序10次跟排序100所需要的基本操作数必然是不同的。因此考虑算法输入规模的具体操作数即不现实也没必要。所以在算法分析中,可以建立以输入规模n为自变量函数T(n)来表示算法的时间复杂度;用大写O()来表示时间复杂度的写法(简称大O记法)。随着n的增大,T(n)增长最慢的为最优算法。
      大O推导法:


  • 用常数1取代运行时间中的所有加法常数
  • 在修改后的运行函数中,只保留最高阶项
  • 如果最高阶项存在且不是1,则去除与这个项相乘的常数

     时间复杂度的计算:
    常数阶:O(1)
   
[C#] 纯文本查看 复制代码
string str = "Hello "; /*执行一次*/            str += "Work"; /*执行一次*/
            Console.WriteLine(str); /*执行一次*/

    从代码中我们就能看到这个算法的运行次是3次,所以根据大O推导法应记为O(1)。

    线性阶:O(n)
   
[C#] 纯文本查看 复制代码
string str = "Hello "; /*执行一次*/
            str += "Work"; /*执行一次*/
            int n = 100;/*执行一次*/
            for (int i = 0; i < n; i++)/*执行(n+1)次*/
            {
                Console.WriteLine(str); /*执行n次*/
            }

    从代码注释可以看到算法的运行次数为 3+(n+1)+n=2n+4,根据大O推导法只保留最高阶项2n,去掉2n这个项的相乘常数,所以此算法的时间复杂度为O(n)。
     
     对数阶:O(log?(n))[?:表示底数]
     
[C#] 纯文本查看 复制代码
string str = "Hello "; /*执行一次*/
            str += "Work"; /*执行一次*/
            int n = 10,i=3;/*执行一次*/
            while (i>n)/*执行log3(n)+1次*/
            {
                i *= 3;/*执行log3(n)次*/
                Console.WriteLine(str);/*执行log3(n)次*/
            }

     因为i每次的乘积是3,固i=3^x>n时循环结束,所以While运行次数为log3(n)+1;因此算法的运行次数为3+log3(n)+1+log3(n)+log3(n)=4+3log3(n),根据大O推导法,保留最高阶项和去掉项的相乘常数,所以此算法的时间复杂度为O(log3(n))。

      平方阶:O(n^2)
[C#] 纯文本查看 复制代码
 string str = "Hello "; /*执行一次*/
            str += "Work"; /*执行一次*/
            int n = 100,num=0;/*执行一次*/
            for (int i = 0; i < n; i++)/*执行n+1次*/
            {
                for (int j = 0; j < n; j++)/*执行n(n+1)次*/
                {
                    Console.WriteLine(str);/*执行n*n次*/
                }
            }


     上面的程序是在内循环上加多一个外循环,从上面的线性阶我们就知道循环的时间复杂度为O(n),所以在循环外加入外循环等于O(n*n),固时间复杂度为O(n^2)。
注:如内外层循环次数不一样时,时间复杂度应为O(n*m)。

   时间复杂度所耗时间:
    O(1) < O(logn) < O(n) < O(nlogn) < O(n2) < O(n3) <O(2n) < O(n!) <O(nn)

      心细的人可能会发现最后的几项时间复杂度没有说明,因为如果你的算法时间复杂度到了O(2n)你就应该考虑重新写过算法。
ibcadmin | 2018-9-13 17:56:07 | 显示全部楼层
+1 , 论坛靠你一个人撑起来了
C#论坛 www.ibcibc.com IBC编程社区
C#
C#论坛
IBC编程社区
剑弑 | 2018-9-14 20:09:52 | 显示全部楼层
ibcadmin 发表于 2018-9-13 17:56
+1 , 论坛靠你一个人撑起来了

过奖过奖,还得靠楠哥你呢
*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则