• (四)两种实现的效率


    1. 算法的基本操作(basic operation)是那些对其总的时间需求贡献最大的因素。
    2. 为什么复杂度只关注最高次项:比如(n2+n)/2---> n2。因为对于大的n值n2比n大得多,所以(n2+n)/2的表现n2/2一样,其次,当n变大时,n2/2的表现n2一样,所以,对于大的n,(n2+n)/2与n2相差不大,且可被忽略。【同一问题考虑大的问题:因为在小问题上,两种方案在执行时间上的差异通常微不足道
    3. 常见增长率函数的相对大小(log的底数不成问题

    1 < log(log n) < log n < log2 n < n < n log n < n2 < n3 < 2n < n!

      4. 最优、最差和平均:最优情况下仍然很慢,说明需要更换算法;最差情形下可以接受,说明算法就是可以接受的。但是最优和最差在实际中很少出现,所以需要考虑算法的平均情形(不是最优和最差的平均值)。---> 依赖于数据本身

      不依赖于数据本身,而依赖于数据个数---> 寻找n个数里的最小值  

      5. O的形式化定义

    函数f(n)具有最多g(n)阶(即f(n)是O(g(n))),如果

    • 给定正实数c和正整数N,对于所有的n ≥ N,存在f(n) ≤ c x g(n)。

     即,当n足够大时, c x g(n)是f(n)的上界。

      f(n)是O(g(n))意味着,当n充分大时,c x g(n)为f(n)的增长率提供了一个上界。对于足够大的数据集(set),算法总是需要少于c x g(n)个基本操作。

    6. 分析实现ADT包的效率

    6.1 基于固定数组的实现

    1)添加add   O(1)

    public boolean add(T newEntry) {
      checkInitialization();   // O(1)
      boolean result = true;   // O(1)
      if(isArrayFull()) {      // O(1) 条件
        result = false;
      }
      else {                   // O(1)
        // Assertion : result is true here
        bag[numberOfEntries++] = newEntry;
      } // end if
      return result;
    }
    // end add private void checkInitialization() {   if(!initialized) {     throw new SecurityException("ArrayBag object is not initialized properly.");   } } // end checkInitialized private boolean isArrayFull() {   return numberOfEntries >= bag.length; } // end isArrayFull

      add方法内部没有循环结构,只有if,else条件分支,均为O(1),所以add为O(1)

    2)查找contains    O(n)

    public boolean contains(T anEntry) {
      checkInitialization();            // O(1)
      return getIndexOf(anEntry) > -1;   // O(n)
    } // end contains
    
    private int getIndexOf(T anEntry) {
      int getIndex = -1;             // O(1)
      if (numberOfEntries > 0) {     // O(1)
        for (int index = 0; index < numberOfEntries; index++) {    // O(n)
          if (bag[index].equals(anEntry)) {
            getIndex = index;
            break;
          } // if
        } // end for
      } // end if
      return getIndex;
    } // end getIndexOf

      因为函数getIndexOf需要遍历数组查找,所以getIndexOf是O(n),函数contains方法体调用checkInitialization函数,为O(1),return调用getIndexOf方法,所以函数contains为O(n)。

    6.2 基于链式的实现

    1)添加add    O(1)

    public boolean add(T newEntry) {  // OutOfMemoryError posiible
        Node newNode = new Node(newEntry);  // O(1)
        newNode.next = firstNode;    //  O(1)
        firstNode = newNode;         //  O(1)
        numberOfEntries++;          //  O(1)
        return true;
    } // end add

      只涉及一些赋值操作,时间为O(1)

    2)查找contains  O(n)

    public boolean contains(T anEntry) {
        Node currentNode = firstNode;             // O(1)
        boolean found = false;                    // O(1)
        while(!found && (currentNode != null)) {   // O(n)
            if(currentNode.data.equals(anEntry)) {   
                found = true;
                break;
             }
            else {
                currentNode = currentNode.next;
            } // end if
        } // end while
        return false;
    } // end contains

      同样需要遍历操作,时间O(n)

    6.3 两种实现的比较

    操作

    固定大小数组

    链式

    add(newEntry)

    O(1)

    O(1)

    remove()

    O(1)

    O(1)

    remove(anEntry)

    O(n)

    O(n)

    clear()

    O(n)

    O(n)

    getFrequencyOf(anEntry)

    O(n)

    O(n)

    contains(anEntry)

    O(n)

    O(n)

    toArray()

    O(n)

    O(n)

    getCurrentSize(),isEmpty()

    O(1)

    O(1)

  • 相关阅读:
    百度echarts插件x轴坐标显示不全决解方法
    Laravel
    Mysql 递归获取多重数组数据
    Laravel 怎么使用资源控制器delete方法
    Laravel 怎么在 blade 视图中将带 HTML 字符原样输出
    laravel sql复杂语句,原生写法----连表分组
    mysql连表分组报错---- sql_mode=only_full_group_by问题解决
    Bootstrap -- 模态框实现拖拽移动
    xcode6模拟器UITextField不能自动弹出键盘
    在Linux系统中使用rpm包安装FTP服务
  • 原文地址:https://www.cnblogs.com/datamining-bio/p/9626943.html
Copyright © 2020-2023  润新知