Python資料結構與演算法_第1節_引入概念

IrisEpode發表於2020-11-17

引入

  • 注意:命名時,py檔名最好為數字_英文,為了防止檔名與package名字重合。

第一次嘗試

  • 如果 a+b+c=1000,且 a 2 + b 2 = c 2 a^2 + b^2=c^2 a2+b2=c2(a,b,c 為自然數),如何求出所有a、b、c可能的組合?
    • 看到這道題,如果不用math的方法,第一個反應就是把他們全部列出來,試一遍 ---- 列舉法
# 列舉法來解決解方程式的問題:三重迴圈
for a in range(0, 1001):
    for b in range(0, 1001):
        for c in range(0, 1001):
            if a**2 + b**2 == c**2 and a+b+c == 1000:
                print("a, b, c: %d, %d, %d" % (a, b, c))

end_time = time.time()
print("elapsed: %f" % (end_time - start_time))
print("complete!")

演算法的提出

  • 演算法是計算機處理資訊的本質,因為計算機程式本質上是一個演算法來告訴計算機確切的步驟來執行一個指定的任務。
  • 演算法是獨立存在的一種解決問題的方法和思想
  • 裘宗燕 《資料結構與演算法 Python語言描述》
  • 《演算法導論》
  • 《資料結構預演算法 C語言描述》要比Python的深一些

演算法的五大特性

  • 輸入: 演算法具有0個或多個輸入
  • 輸出: 演算法至少有1個或多個輸出
  • 有窮性: 演算法在有限的步驟之後會自動結束而不會無限迴圈,並且每一個步驟可以在可接受的時間內完成
  • **確定性:**演算法中的每一步都有確定的含義,不會讓其他人不理解,出現二義性
  • **可行性:**演算法的每一步都是可行的,也就是說每一步都能夠執行有限的次數完成

第二次嘗試

  • 剛剛的演算法效率太低,我們可以根據a、b、c之間的關係來精簡程式碼。
# 列舉法來解決解方程式的問題:兩重迴圈
for a in range(0, 1001):
    for b in range(0, 1001-a):	# 因為b和c不會佔用已選擇出來的、a的數值
        c = 1000 - a - b
        if a**2 + b**2 == c**2:
            print("a, b, c: %d, %d, %d" % (a, b, c))

演算法效率衡量

執行時間反應演算法效率

  • 實現演算法程式的執行時間可以反應出演算法的效率,即演算法的優劣。
  • 但是單純靠執行時間來比較演算法的優劣並不一定是客觀準確的!因為計算機的環境不同。

時間複雜度與“大O記法”

  • 每臺計算機執行的總時間不同,但是執行基本運算數量大體相同。
  • 時間複雜度:程式執行時候,基本的運算數量
    • 第一次嘗試中:
      • T(時間複雜度) = 1000 ∗ 1000 ∗ 1000 ∗ 2 1000 * 1000 *1000* 2 1000100010002,跟問題的規模有關係
      • 假設 a + b + c = n a+b+c=n a+b+c=n T ( n ) = n 3 + 2 T(n) = n^3 +2 T(n)=n3+2

如何理解“大O記法”

  • 更關心數量級,不那麼關心繫數。
  • T ( n ) = n 3 ∗ 2 T(n) = n^3 *2 T(n)=n32 T ( n ) = n 3 ∗ 2 T(n) = n^3 *2 T(n)=n32 在同一個數量級,影像走向也一樣。都為 g ( n ) = n 3 g(n) = n^3 g(n)=n3級。 g ( n ) g(n) g(n)就是 T ( n ) T(n) T(n)的漸進函式(忽略函式),記為 f ( n ) = O ( g ( n ) ) f(n) = O(g(n)) f(n)=O(g(n))

最壞時間複雜度

  • 資料的情況不同,資料處理所需要的步驟也不同。
  • 演算法完成工作最少需要多少基本操作,即最優時間複雜度,參考價值不高。
  • 演算法完成工作最多需要多少基本操作,即最壞時間複雜度,一般考慮的也是他。
  • 演算法完成工作平均需要多少基本操作,即平均時間複雜度,關注度最小。

時間複雜度的幾條基本計算規則

  1. 基本操作,即只有常數項,認為其時間複雜度為O(1),不能算進來函式呼叫
  2. 順序結構,時間複雜度按加法進行計算
  3. 迴圈結構,時間複雜度按乘法進行計算
  4. 分支結構,取最複雜分支的時間複雜度
  5. 判斷一個演算法的效率時,往往只需要關注運算元量的最高次項,其它次要項和常數項可以忽略。
  6. 在沒有特殊說明時,我們所分析的演算法的時間複雜度都是指最壞時間複雜度

演算法分析

  • 第一次嘗試: O ( n 3 ) O(n^3) O(n3)
  • 第二次嘗試: O ( n 2 ) O(n^2) O(n2)

常見時間複雜度

執行次數函式舉例非正式術語
12O(1)常數階
2 n + 3 2^n+3 2n+3O(n)線性階
3 n 2 + 2 n + 1 3n^2+2n+1 3n2+2n+1 O ( n 2 ) O(n^2) O(n2)平方階
5 l o g 2 n + 20 5log_2n+20 5log2n+20 O ( l o g ( n ) ) O(log(n)) O(log(n))對數階
2 n + 3 n l o g 2 n + 19 2n+3nlog_2n+19 2n+3nlog2n+19 O ( n l o g ( n ) ) O(nlog(n)) O(nlog(n))nlogn階
6 n 3 + 2 n 2 + 3 n + 4 6n^3+2n^2+3n+4 6n3+2n2+3n+4 O ( n 3 ) O(n^3) O(n3)立方階
2 n 2^n 2nO(2^n)指數階

常見時間複雜度之間的關係

  • 根據影像的關係判斷時間複雜度的判斷
  • O ( 1 ) < O ( l o g n ) < O ( n ) < O ( n l o g n ) < O ( n 2 ) < O ( n 3 ) < O ( 2 n ) < O ( n ! ) < O ( n n ) O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n) O(1)<O(logn)<O(n)<O(nlogn)<O(n2)<O(n3)<O(2n)<O(n!)<O(nn)

Python內建型別效能分析

  • 時間複雜度為O(1)的是基本操作行,不是函式。
  • 比如list.append()這個函式的時間複雜度不是1。可以有timeit模組來判斷。

timeit模組

  • timeit模組可以用來測試一小段Python程式碼的執行速度。
  • class timeit.Timer(stmt=‘pass’, setup=‘pass’, timer=)
    • Timer是測量小段程式碼執行速度的類。
    • stmt引數是要測試的程式碼語句(statment);
    • setup引數是執行程式碼時需要的設定;
    • timer引數是一個定時器函式,與平臺有關。
  • timeit.Timer.timeit(number=1000000)
    • Timer類中測試語句執行速度的物件方法。number引數是測試程式碼時的測試次數,預設為1000000次。方法返回執行程式碼的平均耗時,一個float型別的秒數。
# 用timeit模組測試建立list的一個操作的效率
from timeit import Timer
def test1():
	l = []
	for i in range(1000):
		l.append(i)
t1 = Timer("test1()", "from __main__ import test1")	# setup是設定環境,在當前檔案內呼叫內部檔案,檔名為__main__
print("append", t1.timeit(number = 1000), "seconds.")
# 在append列表的時候,extend和 +=更快一點,不要使用+。

list內建操作的時間複雜度

在這裡插入圖片描述

dict內建操作的時間複雜度

在這裡插入圖片描述

資料結構

  • 我們希望演算法解決問題的效率越快越好,於是我們就需要考慮資料究竟如何儲存的問題,這就是資料結構。

概念

  • 序列已經是Python封裝的一種高階結構了。資料結構就是對基本資料型別的一次封裝,把他們組合在一起。

演算法與資料結構的區別

  • 資料結構只是靜態的描述了資料元素之間的關係。
  • 高效的程式需要在資料結構的基礎上設計和選擇演算法。
  • 程式 = 資料結構 + 演算法

抽象資料型別(Abstract Data Type)

  • 抽象資料型別(ADT)的含義是指一個數學模型以及定義在此數學模型上的一組操作。即把資料型別和資料型別上的運算捆在一起,進行封裝。
  • 最常用的資料運算有五種:
    • 插入
    • 刪除
    • 修改
    • 查詢
    • 排序

相關文章