Computer programming and database - 考試整理

蜜色發表於2020-12-28

Python考試整理


基於課堂內容的基礎程式碼整理&清晰的說明參考文件:

1. 排序

  1. 插入排序 Insertion-Sort
    參考文章:https://www.jianshu.com/p/c49884d8805e
    個人理解重點:迴圈裡不能用l[j]代替l[i+1], 進入迴圈不止一圈,將新比較值送到正確的位置
    課堂標準程式碼:
def insertion_sort(l):
    for j in range(1, len(l)):
        key = l[j]
        i = j-1
        while i >= 0 and l[i] > key:
            l[i+1] = l[i]
            i -= 1
        l[i+1] = key
    return l


l = [4,-2,-3,1]
assert insertion_sort(l) == [-3, -2, 1, 4]
  1. 歸併排序 Merge-Sort
    參考文章:https://www.cnblogs.com/chengxiao/p/6194356.html
    個人理解重點:recursive裡merge的輸入list,最終是兩個元素的比較,逐層向外擴充套件list
    課堂標準程式碼:
# Uncomment the print expressions to see what's going on, and for debugging
def merge_sort(l, start=0, end=len(l)):
    if end-start > 1:
        j = (end + start) // 2
#         print(f"start={start} end={end} j={j}")
#         print(f"FIRST {start}:{j}")
        merge_sort(l, start, j)
#         print(f"SECOND {j}:{end}")
        merge_sort(l, j, end)
#         print("MERGE")
        merge(l, start, end)
    return l
    
def merge(l, start, end):
    A = []
    j = (end + start) // 2
    ia = start
    ib = j
#     print(f"start={start} end={end} ia={ia} ib={ib} j={j} ")
    while ia < j or ib < end:
#         print(f"IN LOOP ia={ia} ib={ib} j={j} ")
        if ib < end and ia < j: 
            # Both halves are not exhausted
            if l[ia] < l[ib]:
                A.append(l[ia])
                ia += 1
            else:
                A.append(l[ib])
                ib += 1
        elif ib < end:
            # Left half is exhausted
            A.append(l[ib])
            ib += 1
        else:
            # Right half is exhausted
            A.append(l[ia])
            ia += 1

    # Copy back the ordered sublist in l
    for i in range(len(A)):
        l[start+i] = A[i]

  1. 與python自帶sort比較
    結論:對於大量資料,merge好於insertion;python自帶的sort最快
import random #import this for generating random numbers

for n in [10,100,1000]:
    print(f"TEST n={n}")
    l = [random.random() for i in range(n)]  # use list comprehension to build the list
    print("insertion_sort : ",end='')
    %timeit insertion_sort(l.copy()) # use copy otherwise l gets sorted and life is easier for next algorithm
    print("merge_sort : ",end='')
    %timeit merge_sort(l.copy(), 0, len(l))
    print("standard library sort : ",end='')
    %timeit l.copy().sort()   # l.copy() returns a copy of the list and then I call .sort() method on that
    
# - Standard lib implementation is much fasterdd
# - merge_sort becomes better than insertion_sort for large n
TEST n=10
insertion_sort : 7.36 µs ± 460 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
merge_sort : 23.8 µs ± 1.13 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
standard library sort : 325 ns ± 9.4 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
TEST n=100
insertion_sort : 493 µs ± 13.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
merge_sort : 352 µs ± 3.95 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
standard library sort : 3.81 µs ± 134 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
TEST n=1000
insertion_sort : 53.3 ms ± 1.64 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
merge_sort : 5.1 ms ± 23.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
standard library sort : 107 µs ± 3.73 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

tbc

相關文章