一、評估算法復雜度
舉例:
算法復雜度為O(n):
算法復雜度為O(n2):
算法復雜度為O(1+2+...+n) ---> O(n2):
算法復雜度為O(lgN):
算法復雜度為O(1):
高斯解決1+2+3+....+100的辦法 (1+100)*50 常數階算法
二、常見函數的復雜度計算
橫軸代表數據規模,縱軸代表所花時間,這個圖很重要,希望大家記住。
直觀地看算法復雜度與處理規模與所花時間的關系 100000000次運算大概1秒
所以在日常算法的設計中,需要盡量把算法復雜度優化到接近成O(lgN)。
三、順序查找與二分查找的性能對比
代碼:
public class Contrast { public static void main(String[] args) { int []x = new int[10000*10000]; for (int i = 0; i < x.length; i++) { x[i] = i+1; } int target = 10000*10000; long now = System.currentTimeMillis(); // 統計當前時間的方法 int index = binarySearch(x, 0, x.length-1, target); System.out.println("二分查找所需時間:"+(System.currentTimeMillis()-now)+"ms"); System.out.println(target+"所在位置為:"+index); now = System.currentTimeMillis(); index = search(x, target); System.out.println("順序查找所需時間:"+(System.currentTimeMillis()-now)+"ms"); } /** * 二分查找 非遞歸 * @param arr * @param low * @param high * @param key * @return */ static int binarySearch(int arr[],int low,int high,int key){ while(low<=high){ int mid = low + ((high-low) >> 1); // (high+low) >>> 1 防止溢出,移位更加高效,同時,每次循環都需要更新 int midVal = arr[mid]; if (midVal<key) { low = mid +1; }else if (midVal>key) { high = mid - 1; }else { return mid; // key found } } return -(low + 1); // key not found } /** * 順序查找 */ static int search(int arr[],int key){ for (int i = 0; i < arr.length; i++) { if (arr[i]==key) { return i; } } return -1; } }
結果:
結論:二分查找時間為0ms,時間幾乎可以忽略不計,可以發現這兩種查找算法的時間相差很大,所以O(lgn)與O(n)的性能差別很大,
四、基礎排序算法的性能對比
二的冪表
冒泡、插入、選擇排序 這些排序算法的時間復雜度就是O(n2)
Arrays.sort() 采用的快速排序,時間復雜度是O(nlgn) 所以有時采用這個方法排序還比上面的排序算法好用。
四、遞歸算法的性能分析
1、子問題的規模下降 T(n/2) 代表每一層丟一半 T(n-1)代表下降一層
2、子問題的答案的處理消耗的時間 每一層消耗的時間 O(1)代表每一層消耗常數時間 O(n)代表每一層消耗線性時間
寫出類似下面的式子。
T(n) = T(n-1) +O(1)