> 資料結構模組 deque * queue(佇列):先進先出(FIFO, First-In-First-Out) * stack(堆疊):先進後出(First-In-Last-Out) * 一棵二元樹就是由根節點(root),及左子樹(left tree)/右子樹(right tree)所構成。每個節點上有可能連結左右節點,也可能沒有連接,稱為NIL,在Python為None。 * Level-order Traversal(層序遍歷):按照一層一層順序來走遍整個樹,並分層記錄 ⚠️ deque作為queue使用時,主要會用popleft()跟append()來操作,同時它會適合按先後順序放入及取出的情況 > 資料結構模組 heapq * heap (堆積):一種特別的完全二元樹,直到最後一層之前,由左往右都是填滿節點的狀態,中途沒有空缺,唯有最後一層的右側會缺節點而已 * 最小堆積(min heap):對應父(母)節點的值永遠**小於等於**子節點的值(就是越上面越小) * 最大堆積(max heap):父(母)節點的值永遠**大於等於**子節點的值 ⚠️ 最大堆積的最大節點永遠會在根節點;最小堆積的最小節點永遠會在根節點 * 透過heapq.heapify()函式,將list輸入給heapq來排成heap的形狀 | 方法 | 作用 | | ---- | ---- | |heapify|將一個list轉為heap| |heappush|放入元素到heap中| |heappop|取出元素到heap中| |heappushpop|先放入一個元素到heap中,再從heap取出一個元素| |nlargest|取出前n大的元素| |nsmallest|取出前n小的元素| * 當使用append或者del ( 也就是用list的方式來動到lt ) 時,會影響heap的狀態,若要復原只能重新heapify() * 由於這個heap是min heap,所以nsmallest ( 取前n小元素 ) 速度會比較快,較有效率,nlargest ( 取前n大元素 ) 是較沒有效率的 * 當需要用到max heap時,我們手動將每個元素加上一個**負號**代入 > 二元搜尋法模組 bisect * 當有一串排列好的陣列/串列時,可透過每次去掉一半來迅速找到目標 * 取l=0, r=n-1的中間位置mid=(l+r)//2時,會有幾個可能: ``` lt[mid] > target => 代表target在mid左邊的位置,所以要搜尋的範圍就會變成0~mid-1 lt[mid] == target => 代表target在mid位置上,可以直接回傳結果 lt[mid] < target => 代表target在mid右邊的位置,所以要搜尋的範圍就會變成mid+1~r ``` * bisect模組的常見用法 | 用法 | 作用 | | ---- | ---- | | bisect_left|取得應該插入的位置,碰到相同的值,會以插入在所有相同的值得左邊為準| |bisect_right|取得應該插入的位置,碰到相同的值,會以插入在所有相同的值得右邊為準| | bisect | 取得應該插入的位置(預設方法,同於bisect_right) | | insort_left | 同bisect_left,但回傳應插入的位置後,會實際使用該inddex進行插入的動作 | | insort_right | 同理,比bisect_right多了實際插入的動作 | | insort | 同insort_right | ⚠️ 上述所有函式的參數都是「a, x, lo=0, hi-len(a)」,a為要插入的目標串列,x為要插入的值,lo和hi分別界定要搜尋的範圍,沒有特別指定的話就會當作使用整個串列考慮插入的問題。 ⚠️ 使用bisect查找的速度,扣除掉重覆值找到最左邊/最右邊外,其時間複雜度為O(logN)。(log這邊是以2為底的) * 複雜度:就是用來評估程式作一件事情,其所需的時間/空間和輸入的資料大小(通常會用N表示)之間,大致的量級關係。 > 科學運算 Numpy * Numpy最基本單位:陣列 ndarray,是一系列的相同資料型態的元素組成 * n維 n-dimension (nd) * numpy的基本指令: | np.array() | 產生一個ndarray | | ---------- | ------------------------- | | ndim | 取得ndarray的維度數(rank) | | shape | 取得ndarray每個維度的元素個數(以Tuple型式呈現) | |size |取得ndarray總元素個數| ⚠️ 相同維度必須要有相同的長度 * arange(): ``` np.arange(10):生成一個維陣列,元素從0~9 np.arange(5, 10):生成一個維陣列,元素從5~9 np.arange(5, 11, 2):生成一個維陣列,元素為5, 7, 9 ``` * zeros():可用來建立全是0的陣列 * ones():可建立全是1的陣列 * random.random():從0.0~1.0取得隨機值來建立一個陣列,當中的每個元素都是獨立的隨機值 * random.normal():最常見的常態分佈的陣列,用法 np.random.normal(平均值, 標準差, size) * reshape():將陣列重新指定維度形狀,reshape會產生另一個新的ndarray,故原先的陣列並不會被變動,除非重新指定陣列的shape,才會變動到原有的陣列 ⚠️ 在取得單一或範圍元素的時候,陣列基本上跟串列蠻像的,但如果是多維陣列的話,則必須要用逗號「,」分隔不同的維度;Python的串列則是用中括號「[]」分隔 * np.dot(x, y) / x.dot(y):算兩個二維矩陣的相乘(內積) * outer():計算外積 * np.multiply():對應位置兩兩相乘 > 科學繪圖 Matplotlib * plt.hist():使用直方圖來表現出點的分布數量,經過plt.show()顯示 * plt.plot(x, y, linewidth):畫線按座標,每個x的元素都對應到y的元素 ⚠️ Python的陣列預設從0開始,所以只給一段座標時,會被當成y座標,且x會從0開始起算,以整數遞增 ⚠️ 以plt.plot的方式繪圖時,畫上去的圖被稱為figure,figure的軸則是axes,可以用add_subplot(1,1,1)方法取用到 * set_title():設定圖的標題 * set_xlabel():設定x軸文字 * set_ylabel():設定y軸文字 * set_suptitle():設定補充標題 ⚠️ 在plt.plot輸入陣列後加上一個格式字串可以用來代表畫線的樣式,指定linewidth可以修改畫線的粗細 * r:紅色 * x:用「x」來表示點且不畫線 * b:藍色 * . :用單個小點表示一個點 * --:用虛線來畫線 * g:綠色 * o:實心圓 ⚠️ 在處理過可畫線的圖後,若資料是零散的點,不需畫線的話,可用 **散點圖(scatter)** 來進行繪製 ⚠️ 繪製3D圖要用plt.axes(),將其projection設為'3d',由於有三維座標,所以要使用ax.scatter3D(x, y, z, color) ⚠️ 儲存圖形方法:將圖plot到plt上後,使用plt.savefig('檔名')即可