zoukankan      html  css  js  c++  java
  • (c#)数据结构与算法分析 运行时间计算

        在比较算法的效率时,往往是算法的运行时间与数据项个数关系间比较,例如,为了得到某个结果,在同一数据量下,哪个算法运行最快,效率最高,而后改变这一数据量,哪种算法的时间又最快......

    大O表示法
        
    在描述算法运行时间时,往往能看到O(N)、O(logN)等,大O中的O的意思就是"order of"(大约是),它是种概念,就比如 大型车、小型车和中型车,忽略具体大小尺寸,来描述汽车。

    首先来跟着我分析一段代码:
    示例 1:
     1 int sum(int n)
     2 {
     3     int partialSum;
     4     partialSum = 0;
     5     for(int i = 1;i <= n;i++)
     6     {
     7         partialSum += i * i * i;
     8     }
     9     return partialSum;
    10 }

    这个程序是计算 Σn i=1 i3 即 从1开始到n的整数,计算它们的立方和

        声明不计时间,赋值、计算、比较每次占一个时间单位,则从第四行开始,首先花费1个时间单位,接着进入循环,给i赋值,又占一个单位,它只运行一次,接着比较,运行n+1次,i++为两次计算,一次加一,一次赋值,而它要运行n次,占2n个时间单位,循环主体是四个时间单位(两个乘法,一个加法,一个赋值),总共执行n次,故花费4n个单位,最后返回花费1个时间单位。

        最终,这个程序总共花费1(赋值)+1(赋值)+(1+2n)(比较)+4n(计算)+1(返回)=6n+4 个时间单位,但是,如果每个程序都像这样计算的话,岂不是让人崩溃,大O表示法的宗旨就是,舍去所有常量,把它归入cpu,平台等因素造成的时间,假设这些常量总体为K,则上面那个程序所花费的时间是n+K,按照这种计算方式,每个程序的运行时间都会转化为xn+K,所以我们可以把K舍去。

        最终,以大O表示法,这个程序的运行时间是O(N)。

        如果是一个嵌套循环呢,比如:
    示例 2:
    for(int i=0;i<n;i++
    {
        
    for(int j=0;j<i;j++)
        {
            代码;
        }
    }

    这段代码的运行时间就为O(N2)了 (自己按照上面那种方法掐指算一下)。

        如果把实例2添加进示例1中的返回语句前,则运行时间为n+n2,以大O表示法则为O(n2)。

        看到了吧,大O表示法是没有加号的,所有这些都被忽略了,没有常数,只有迭代次数。

        很多与我一样数学底子不好的同学,遇到O(logN)等这样带对数的时候就会迷茫,其实也不难,拿二分搜索举例,它的运行时间是O(logN)。

        什么是二分搜索?我来举个例子,李咏大哥让你猜个电器的价格,猜中了就归你了,如果你聪明的话,就不会乱猜,你会首先随机猜一个自己认为适合的价格(比如一个电视,你猜5000),如果他喊低了,就继续往上加,但是他喊高了,你会选择刚才价格的一半(2500),如果他喊高了,则继续折一半(1250),这次他喊低了,你就猜3750,按照这种原则,你最终猜对了,是3750,你只用了3次。

        按照这种方法,最坏的情况下(即猜的次数最多),N个数所用的次数X<=log2N ,因为2x<=n,比如10个数,最多猜测3次,即23<=10 ,3<=log210 。
        
        现在大致明白了log形式的运行时间了吧。

        这里列出一些运行时间计算的一些法则,是从《数据结构与算法分析C++描述(第三版)》上面摘录的

    法则1:for循环  一个for循环的运行时间至多是该for循环内语句(包括测试)的运行时间乘以迭代的次数。

    法则2:嵌套循环  从里向外分析这些循环。在一组嵌套循环内部的一条语句总的运行时间为该语句的运行时间乘以该组所有循环的大小的乘积。

    法则3:顺序语句  将各个语句的运行时间求和即可(这意味着,其中的最大值就是所得的运行时间)。

    法则4:IF/ELSE语句  一个if/else语句的运行时间从不超过判断再加上每个主体中运行时间较长者的总的运行时间。

        最后,总结一下,其实运行时间O就是相对增长率,我们所比较的运行时间,就是把他们的相对增长率进行比较,这里的运行时间,都是在最坏情况下得出的,因为数据量充满不确定性,不保守估计的话,会出错,了解了运行时间的算法,对一个算法的好坏的判断就有基准了,以后会用到这里(尤其是排序算法)。

        我所理解的很可能有错误,希望高手拍砖指正,谢绝打击的言论,毕竟我不懂高数,这个设计到了极限。


    ps:我们当时排序算法就只教了冒泡,就连快速排序都不知道是什么,现在同学们遇到排序,都是冒泡
    还好,我学了比较多的排序算法,每个都有自己的应用场景,我以后的笔记会讨论排序的,真希望我的同学们能看看这些笔记。
  • 相关阅读:
    解决错误:Your ApplicationContext is unlikely to start due to a @ComponentScan of the default package.
    IDEA编译时出现 Information:java: javacTask: 源发行版 1.8 需要目标发行版 1.8
    发票打印不全不完整的解决方案(Win10)
    Idea checkstyle插件的使用
    .Net转Java.08.format
    修复恢复"可疑"的SQLServer数据库
    .Net转Java.07.IDEA和VS常用操作、快捷键对照表
    .Net转Java.06.字符串的split的区别
    .Net转Java.05.为啥MySQL没有nolock
    .Net转Java.04.踩到switch的坑
  • 原文地址:https://www.cnblogs.com/hangxin1940/p/1138297.html
Copyright © 2011-2022 走看看