1. 程式人生 > >《資料結構與演算法 Python語言描述》 讀書筆記

《資料結構與演算法 Python語言描述》 讀書筆記

已經發布部落格

《資料結構與演算法 Python語言描述》 讀書筆記

 

第二章 抽象資料型別和Python類

2.1 抽象資料型別abstract data type:ADT 

2.1.1

使用程式語言提供的資料組合機制(元組,列表等)對處理複雜程式裡的資料組織問題是不夠的。

 

2.1.2 抽象資料型別的概念

把資料定義為抽象的物件集合,為他們定義合法操作,不暴露內部實現細節。

資料型別的變動性,表示資料被建立後是否可以變化。

 

2.1.3 抽象資料型別的描述 

抽象資料型別的結構:

1 一個ADT描述由一個頭部和按照一定格式給出的一組操作描述構成。

2 頭部給出型別名字,最前面是關鍵詞ADT,表明抽象資料型別。

3操作形式描述給出操作名字,引數型別,引數名字

4 各個操作的實際功能用自然語言描述,說明這個操作具體能做什麼。

 

2.2 Python的類

2.2.1 有理數類

 

rational有理數

gcd:greatest commen divisor最大公約數

2.2.2 類定義進階                                                           

類機制定義的型別和Python系統內部型別用法相同。

靜態方法:在類裡定義的普通函式

2.3  類的定義和使用

2.3.1 基本的類定義和使用

2.3.2 例項物件:初始化和使用

P46

2.3.3 

靜態方法:@staticmethod:實際就是定義在類裡面的沒有self的普通函式,

類方法:@classmethod:這種方法必須有一個表示其呼叫類的引數,習慣用cls作為引數名,還可以有任意多個其他引數。

isinstance(obj, cls) 函式來判斷一個物件是否是一個已知的型別,類似 type()。 

 

 

isinstance() 與 type() 區別:

 

type() 不會認為子類是一種父類型別,不考慮繼承關係。

 

 

isinstance() 會認為子類是一種父類型別,考慮繼承關係。 

 

 

如果要判斷兩個型別是否相同推薦使用 isinstance()。

 

語法

 

以下是 isinstance() 方法的語法:

isinstance(object, classinfo)

 

引數

object -- 例項物件。

classinfo -- 可以是直接或間接類名、基本型別或者有它們組成的元組。

 

返回值

 

如果物件的型別與引數二的型別(classinfo)相同則返回 True,否則返回 False。。

 

 

例項

 

以下展示了使用 isinstance 函式的例項: 

 

 

>>>a = 2

>>> isinstance (a,int)

True

>>> isinstance (a,str)

False

>>> isinstance (a,(str,int,list))    # 是元組中的一個返回 True

True

 

2.3.4 繼承

虛擬函式:通過動態約束確定呼叫關係的函式

基類:父類

派生類:子類

標準函式:super()

2.4 python異常

異常都是類,所有異常的基類是BaseException.最重要的子類是Exception,內建異常類都是這個類的直接後者間接派生類。

 

2.4.3 內建的標準異常類

 

2.5類定義例項:學校人事管理系統中的類

2.5.1 問題分析和設計

學生和老師有共性也有特殊性,先定義一個公共人員類,然後從中派生出學生類和教職工類。

基於人員ADT的設計

學生ADT的設計

教職工ADT的設計

 

2.5.2 人事記錄類的實現

2.5.3 討論:

定義派生類的用途:

 

第三章 線性表

3.1 線性表的概念和表抽象資料型別

3.1.1 表的概念和性質

線性表就是有限個數據排列,第一個元素叫做首元素的下標是零,第n個元素的下標是n-1。

3.1.2 表抽象資料型別

線性表的操作

建立線性表,檢查資料表,修改表,組合表,操作表元素

3.1.3 線性表的實現:基本考慮

順序表和連結表

3.2 順序表的實現

 3.2.1 基本實現方式

3.2.2 順序表基本操作的實現

建立空表,簡單判斷操作,訪問給定下標i的元素。便利操作,查詢給定元素d的位置,查詢給定元素d在位置k之後的第一次出現的位置。

變動操作:加入元素,刪除元素,

3.2.3 順序表的結構

兩種基本實現方式

一體式結構:儲存表資訊的單元和元素儲存區以連續的方式安排在一塊儲存區裡。

分離式結構:

替換元素儲存區:分離式結構的優點,表頭不變,變換元素內容

後端插入和儲存區擴充:動態順序表技術,每次增加10個元素儲存位置。

3.2.4 Python的list

tuple是不變的表,因此不支援改變其內部狀態的任何操作。

list是元素個數可以變化的線性表。,可以新增,可以刪除。

list採用分離式技術實現的動態順序表。

3.2.5 順序表的簡單總結 

3.3 連結表

3.3.1 線性表的基本需要和連結表

3.3.2 單鏈表 

單鏈表:每個表結點裡記錄著儲存下一個表元素的結點的標識和本身結點的資料項

表頭變數,表頭指標,表尾結點設定空連結,

基本連結串列操作:

建立空連結串列,刪除連結串列,判斷連結串列是否為空,

加入元素:

表首端加入,表中間插入,表尾插入。

3.4 連結串列的變形和操作

3.4.1 單鏈表的簡單變形

通過繼承和擴充定義新連結串列類

子類可以繼承父類,可以定義新的方法,可以覆蓋父類的方法。

任何使用者定義類都是object類的子類。

初始化和變動操作

鐳射機的內在一致性

3.4.2 迴圈單鏈表

最後一個節點的next域指向第一個結點。

3.4.3 雙鏈表

單鏈表只能首端新增和刪除,尾端加入。只能做一個方向的掃描

雙鏈表就可以首端和尾端都進行刪除和加入操作。可以做兩個方向的掃描。

單鏈表只能找到下一個結點,要找到前一個結點,只能從表頭開始掃描。

雙鏈表可以直接找到前後兩個結點,

迴圈雙鏈表

3.4.4 兩個連結串列操作

連結串列反轉

 

連結串列排序

3.4.5 不同連結串列的總結

 

第四章 字串 

4.1 字符集,字串和字串操作

字符集,

字元序

4.1.1 字串相關概念

字串長度,字元在字串裡的位置,字串相等,字典序,字串拼接,子串關係,字首和字尾,n次冪。

4.1.2 字串抽象資料型別

4.2 字串的實現

4.2.1 基本實現問題和技術

4.2.2 實際語言裡的字串

4.3字串匹配

4.3.1 字串匹配

4.3.2 串匹配和樸素匹配演算法

4.3.3 無回溯串匹配演算法(KMP演算法)

4.4 字串匹配問題

4.4.1 串匹配和搜尋的不同需要 

模式,字串和串匹配

萬用字元和簡單模式語言

正則表示式regular expression, regex,re,

4.5 python 正則表示式regular

4.5.2 基本情況 

原始字串 

在普通字串前面新增R或者r。其中的反斜線\不是轉義字元

元字元:特殊字元

. ^ $ * + ? \ | {} [ ] () 

4.5.3  主要操作

生成正則表示式物件:re.compile(pattern, flag = 0)

r1 = re.compile("abc") 生成與abc對應的正則表示式物件,並且賦值給r1;

檢索:re.search(pattern,string, flag=0)

匹配:re.match(pattern, string, flag =0)

分割:re.split(pattern,string, maxsplit =0, flags =0)

找出所有匹配串:re.findall(pattern, string, flags=0)

4.5.4 正則表示式的構造

字元組 

某些正則表示式可以和一組字元中的任何一個字元匹配,叫做字元組描述。

字元組描述符[...],和方括號中的任意字元都可以匹配,沒有順序。

區間形式:[0-9]匹配所有十進位制數字

[a-zA-Z]匹配所有字母

 

特殊形式[^...]匹配所有沒有列在中括號裡的東西,字元組求補。

原點字元(.):萬用字元,匹配任何字元

a..b匹配a開頭,b結尾的所有四個字串

re採用轉義串的形式定義了一些常用字元組。

\d 匹配所有十進位制數字

\D 匹配所有非十進位制數字

\s 與所有空白字元匹配,等價於[\t\v\n\f\r]

\w匹配所有字母和數字,等價於[0-9a-zA-Z]

p\w\w 表示字母p開頭的三個字元

重複描述符*

a* 表示匹配n個連續的a,n>=0

re.split('[ ,]*','1 2, 3    4,  , ,5') 得到['1', '2', '3', '4', '5'] 可以與空格或者逗號匹配

貪婪匹配:模式與字串裡有可能匹配的最長子串匹配 re.match('ab*', 'abbbbc') 結果是abbbb

非貪婪匹配:模式與有可能匹配的最短子串匹配

+表示一次或者多次重複,不可以不重複一次

可選描述符:?  表示?前面的字元可要可不要

重複次數描述符:{n}這個符號前面的字串可以出現n次

重複次數的範圍描述符:{m,n} 前面的東西可以出現m到n次,包含,m,n次,m,n可以省略

非貪婪匹配描述符,在運算子後面加上問號?

選擇描述符:|,匹配任何其中一個。 a|b|c,可以匹配a,或者b,或者c

首尾描述符:

行首描述符:^,表示以^後面的字元開頭的一行字串

re.search('^for','books\n for children')找到了for children,因為換行後導致for開頭了一個新行

行尾描述符:$表示用$後面的字元結尾的一行字串

 

re.search('^books','books\n for children')找到books,匹配成功

串首描述符:\A

串尾描述符:\Z 

 

單詞邊界

匹配物件

匹配的子串:mat.group()

匹配起始位置:mat.start()

匹配結束位置:mat.end()

匹配區間:mat.span() 開始和結束位置得到的二元組

模式裡的組:group

正則表示式物件

正則表示式的使用

本章總結 

第五章 棧和佇列 stack and queue

5.1 概述

棧和佇列主要用於在計算過程中儲存臨時資料,是使用最多的快取機制。

運算過程中產生的中間資料暫時不用或者用不完,這些事先無法確定的資料項複雜的機制儲存和管理,稱作快取機制。

5.1.1 棧,佇列和資料使用順序

元素的存入和取出操作

棧:先進後出模式,類似從書堆取書

堆:先進先出,類似超市排隊付款

5.1.2 應用環境

快取結構

計算過程分為一些順序進行的步驟

程序會不斷產生中間資料

有些資料不能立即使用,但是將來可能會使用

資料項數不能事先確定

5.2 棧,概念和實現

5.2.1 棧抽象資料型別

棧的線性表實現

後進先出LIFO

棧頂實行插入,刪除操作,訪問彈出都是棧頂元素。

棧底

 

5.2.2 棧的順序表實現

 

5.2.3 棧的連結表實現

 

5.3 棧的應用

棧是最簡單的資料結構

輔助儲存結構,保證後進先出的順序存取

5.3.1 符號應用:括號匹配問題

5.3.2 表示式的表示,計算和變換

表示式和計算的描述

字尾表示式的計算

中綴表示式到字尾表示式的轉換

中綴表示式的求值

5.3.3 棧與遞迴

在定義中引用了定義本身,稱作遞迴定義。 也就是重複使用本身的意思。

階乘函式的遞迴計算用了程式執行棧

 

棧與遞迴函式呼叫

棧與函式呼叫*

遞迴與非遞迴

遞迴函式與非遞迴函式

簡單揹包問題

 

5.4 佇列 queue

一種容器,可以存入,訪問,刪除元素

5.4.1 佇列抽象資料型別

先進先出型別。FIFO

5.4.2 佇列的連結表實現

5.4.3 佇列的順序表實現

基於順序表實現佇列的困難。

迴圈順序表

5.4.4 佇列的list實現

5.4.5 佇列的應用

檔案列印:待列印檔案都需要快取。

全球資訊網伺服器:淘寶交易高峰期請求高出平時許多倍。伺服器系統不可能立即處理這些請求,就會把來不及的請求放入待處理請求佇列

採取先來先服務原則

Windows系統和訊息佇列:

離散時間系統模擬:

5.5 迷宮求解和狀態空間搜尋

5.5.1 迷宮求解:分析和設計

5.5.2 求解迷宮的演算法

迷宮的遞迴求解

棧和回溯法

5.5.3 迷宮問題和搜尋

5.6 幾點補充

5.6.1 幾種和棧或者佇列相關的結構

雙端佇列 

 

 

測試題:

某表示式的字首形式為"+-*^ABCD/E/F+GH",它的中綴形式為() 

 

  A^B*C-D+E/F/G+H

  

  A^B*(C-D)+(E/F)/G+H

  

  A^B*C-D+E/(F/(G+H))

  

  A^B*(C-D)+E/(F/(G+H))

  

 There is a sequence of n numbers 1, 2, 3,.., n and a stack which can keep m numbers at most. Push the n numbers into the stack following the sequence and pop out randomly. Suppose n is 2 and m is 3, the output sequence may be 1, 2 or 2, 1, so we get 2 different sequences. Suppose n is 7 and m is 5, please choose the output sequences of the stack: 

 

  1, 2, 3, 4, 5, 6, 7

  

  7, 6, 5, 4, 3, 2, 1

  

  5, 6, 4, 3, 7, 2, 1

  

  4, 5, 6, 3, 7, 2, 1

  

  1, 7, 6, 5, 4, 3, 2

  

  3, 2, 1, 7, 6,5, 4

  

  一個棧的入棧序列為ABCDE,則不可能的出棧序列為() 

 

  ECDBA

  

  DCEAB

  

  DECBA

  

  ABCDE

  

  如果進棧序列為e1,e2,e3,e4,則不可能的出棧序列是( )  A.e2,e4,e3,e1

 

B.e4,e3,e2,e1

 

C.e1,e2,e3,e4

 

D.e3,e1,e4,e2

 

解析:

. e1進,e2進,e2出,e3進,e4進,e4出,e3出,e1出

.e1進,e1出,e2進,e2出,e3進,e3出,e4進,e4出

 

 

 

第六章 二叉樹和樹

複雜結構中的最簡單一類結構。

結點儲存資料

樹根,前驅,後繼

6.1 二叉樹:概念和性質

二叉樹每個結點至多關聯到兩個後繼結點。

6.1.1 概念和性質

左子樹和右子樹

小圓圈代表二叉樹的結點

幾個基本概念:

空樹

單點樹

父結點

子結點

從父結點到子節點的邊

傳遞關係:祖先/子孫關係

兄弟結點

祖先結點

子孫結點

樹葉結點

分支結點

結點的度數:子結點的個數

路徑,結點的層和樹的高度

一條路徑,路徑的長度

路徑唯一:從根節點到任意結點

二叉樹是層次結構

樹根是最高元素

路徑長度就是結點層數

高度或者深度是樹中結點的最大層數

二叉樹性質 

長度為n的表裡只能容納n個結點,但是高為h的二叉樹中容納2的h次方個結點。

滿二叉樹

擴充二叉樹

內部結點

新增的外部結點

外部路徑

內部路徑

完全二叉樹:0到h-1層都是滿結點,並且h層(最底層)所有結點在最左邊連續排列

6.1.2 抽象資料型別

6.1.3 遍歷二叉樹

深度遍歷二叉樹:先根序遍歷,中根序遍歷,後根序遍歷

寬度優先遍歷:逐層訪問樹中結點

遍歷與搜尋

搜尋樹

6.2 二叉樹的list實現

6.2.1 設計和實現

6.2.2 二叉樹的簡單應用:表示式樹

二元表示式和二叉樹 

葉結點放運算物件

分支結點放運算子

構造表示式

表示式求值 

6.3 優先佇列

6.3.1概念 

6.3.2 基於線性表的實現

有關實現方法的考慮

採用有組織的元素存放方式和採用無組織的元素存放方式

基於list實現優先佇列

對連續表實現的分析

6.3.3 樹形結構和堆

線性和樹形結構

堆及其性質

資料按照優先關係遞減

根節點:堆頂

小頂堆:小元素在上

大堆頂:大元素在上,優先

6.3.4 優先對列的堆實現

篩選:解決堆插入和刪除的操作。分為向上和向下篩選

插入元素和向上篩選

彈出元素和向下篩選

基於堆的優先佇列

構建操作的複雜性

6.3.5 堆的應用:堆排序

6.4 應用:離散事件模擬

6.4.1 通用的模擬框架

6.4.2 海關檢查站系統

6.5.1 二叉樹結點類 

6.5.2 遍歷演算法 

遞迴定義的遍歷函式

寬度優先遍歷

非遞迴的先根序遍歷函式

通過生成器函式遍歷 

非遞迴的後根序遍歷演算法

6.5.3 二叉樹類 

6.6 哈夫曼樹

是一種重要的二叉樹

6.6.1 哈夫曼樹和演算法

擴充二叉樹:把普通二叉樹補充所有樹葉

帶權擴充二叉樹的外部路徑及其長度:給擴充二叉樹的外部結點標一個數值。這個數值就是權

帶權擴充二叉樹的外部路徑長度WPL: 

哈夫曼樹定義:實數集:W,擴充二叉樹T,二叉樹的帶權外部路徑長度最小。

演算法:從任意的實數集構造與之對應的哈弗曼樹

6.6.2 哈夫曼演算法的實現 

6.6.3 哈夫曼編碼 

6.7 樹和樹林 

6.7.1 例項和表示 

家族關係就是樹。

6.7.2 定義和相關概念 

樹,樹林,二叉樹的關係 

樹林可以和二叉樹相互對映 

6.7.3 抽象資料型別和操作 

樹的遍歷 

搜尋樹

6.7.4 樹的實現 

子結點引用表示,父結點引用表示,子結點表表示

6.7.5 樹的Python實現

 

認識你是我們的緣分,同學,等等,學習人工智慧,記得關注我。

 

微信掃一掃
關注該公眾號

《灣區人工智慧》