两种实现的效率

Posted datamining-bio

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了两种实现的效率相关的知识,希望对你有一定的参考价值。

  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:

 

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

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

 

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

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)


以上是关于两种实现的效率的主要内容,如果未能解决你的问题,请参考以下文章

十条jQuery代码片段助力Web开发效率提升

十条jQuery代码片段助力Web开发效率提升

十条实用的jQuery代码片段

VS Code配置snippets代码片段快速生成html模板,提高前端编写效率

一个具有两种显示类型的片段[关闭]

springMVC两种方式实现多文件上传及效率比较