數據結構和算法之時間空間複雜度(下)

數據結構和算法之時間空間複雜度(上)
上篇文章沒看的話,這篇文章就別看了。

一、知識點

  • 最好時間複雜度(best case time complexity)
  • 最壞時間複雜度(worst case time complexity)
  • 平均時間複雜度(average case time complexity)

二、案例

1、分析時間複雜度

利用上一篇學到的知識點,分析下面這段代碼的時間複雜度是多少。

private int search(int array, int n, int x) {
	int i = 0;
	int pos = -1;
	for (; i < n; i ++) {
		if (array[i] == x) {
			pos = i;
		}
	}
	return pos;
}

這段代碼要實現的功能是,在一個無序的數組(array)中,查找變量 x 出現的位置。如果沒有找到,就返回 -1。時間複雜度很容易,T(n)=O(n)。

2、代碼優化

細心的人會發現這段代碼if裏面沒有break,意味着即使找到了合適的位置也依然會繼續for到結束。我們修正下。

private int search(int array, int n, int x) {
	int i = 0;
	int pos = -1;
	for (; i < n; i ++) {
		if (array[i] == x) {
			pos = i;
			break;
		}
	}
	return pos;
}

3、再次分析時間複雜度

這時候時間複雜度是多少呢?這就需要區分不同的情況了
1.最好的情況就是第一次循環就匹配到了,然後進行了break。這時候T(n)=O(1)
2.最壞的情況就是最後一次循環才匹配到或者說根本沒匹配到,這時候T(n)=O(n)
我簡單粗暴的歸納爲一句話:
既然有最好又有最壞,那就看最好的情況發生概率大還是最壞的情況發生的概率大,哪個概率大,那麼平均時間複雜度就是哪個。比如上段程序的平均時間複雜度就是O(n)

有點過於簡單粗暴,但是很實用。如果要細說,那涉及到概率論和加權平均等等各種數學知識,意義不大。

三、練習

1、代碼


// 全局變量,大小爲10的數組array,長度len,下標i。
int array[] = new int[10]; 
int len = 10;
int i = 0;

// 往數組中添加一個元素
private void add(int element) {
   if (i >= len) { // 數組空間不夠了
     // 重新申請一個2倍大小的數組空間
     int new_array[] = new int[len*2];
     // 把原來array數組中的數據依次copy到new_array
     for (int j = 0; j < len; ++j) {
       new_array[j] = array[j];
     }
     // new_array複製給array,array現在大小就是2倍len了
     array = new_array;
     len = 2 * len;
   }
   // 將element放到下標爲i的位置,下標i加一
   array[i] = element;
   ++i;
}

2、分析

答案:最好時間複雜度是O(1),最差時間複雜度是O(n), 平均時間複雜度是O(1)。

因爲進入if條件的概率遠小於不進入if條件的概率。所以平均時間複雜度取最好的時間複雜度O(1)(也就是if外的,if外的就是O(1),if內的是O(n))。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章