两种实现的效率
Posted datamining-bio
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了两种实现的效率相关的知识,希望对你有一定的参考价值。
- 算法的基本操作(basic operation)是那些对其总的时间需求贡献最大的因素。
- 为什么复杂度只关注最高次项:比如(n2+n)/2---> n2。因为对于大的n值,n2比n大得多,所以(n2+n)/2的表现与n2/2一样,其次,当n变大时,n2/2的表现与n2一样,所以,对于大的n,(n2+n)/2与n2相差不大,且可被忽略。【同一问题考虑大的问题:因为在小问题上,两种方案在执行时间上的差异通常微不足道】
- 常见增长率函数的相对大小(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))),如果
即,当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) |
以上是关于两种实现的效率的主要内容,如果未能解决你的问题,请参考以下文章