日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

python structure_GitHub - CYZYZG/Data_Structure_with_Python: 这是我在学习《基于Python的数据结构》的时候的笔记与代码...

發(fā)布時(shí)間:2025/4/16 python 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python structure_GitHub - CYZYZG/Data_Structure_with_Python: 这是我在学习《基于Python的数据结构》的时候的笔记与代码... 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Data_Structure_with_Python

這是我在學(xué)習(xí)《基于Python的數(shù)據(jù)結(jié)構(gòu)》的時(shí)候的筆記與代碼

主要參考:數(shù)據(jù)結(jié)構(gòu)與算法(Python)

對(duì)于算法的時(shí)間效率,我們可以用“大O記法”來(lái)表示。

“大O記法”:對(duì)于單調(diào)的整數(shù)函數(shù)f,如果存在一個(gè)整數(shù)函數(shù)g和實(shí)常數(shù)c>0,使得對(duì)于充分大的n總有f(n)<=c*g(n),就說(shuō)函數(shù)g是f的一個(gè)漸近函數(shù)(忽略常數(shù)),記為f(n)=O(g(n))。也就是說(shuō),在趨向無(wú)窮的極限意義下,函數(shù)f的增長(zhǎng)速度受到函數(shù)g的約束,亦即函數(shù)f與函數(shù)g的特征相似。

時(shí)間復(fù)雜度:假設(shè)存在函數(shù)g,使得算法A處理規(guī)模為n的問(wèn)題示例所用時(shí)間為T(n)=O(g(n)),則稱O(g(n))為算法A的漸近時(shí)間復(fù)雜度,簡(jiǎn)稱時(shí)間復(fù)雜度,記為T(n)

最壞時(shí)間復(fù)雜度

算法完成工作最多需要多少基本操作,即最壞時(shí)間復(fù)雜度

時(shí)間復(fù)雜度的幾條基本計(jì)算規(guī)則

基本操作,即只有常數(shù)項(xiàng),認(rèn)為其時(shí)間復(fù)雜度為O(1)

順序結(jié)構(gòu),時(shí)間復(fù)雜度按加法進(jìn)行計(jì)算

循環(huán)結(jié)構(gòu),時(shí)間復(fù)雜度按乘法進(jìn)行計(jì)算

分支結(jié)構(gòu),時(shí)間復(fù)雜度取最大值

判斷一個(gè)算法的效率時(shí),往往只需要關(guān)注操作數(shù)量的最高次項(xiàng),其它次要項(xiàng)和常數(shù)項(xiàng)可以忽略

在沒(méi)有特殊說(shuō)明時(shí),我們所分析的算法的時(shí)間復(fù)雜度都是指最壞時(shí)間復(fù)雜度

常見(jiàn)時(shí)間復(fù)雜度

常見(jiàn)時(shí)間復(fù)雜度之間的關(guān)系

timeit模塊

timeit模塊可以用來(lái)測(cè)試一小段Python代碼的執(zhí)行速度。

class timeit.Timer(stmt='pass', setup='pass', timer=)

Timer是測(cè)量小段代碼執(zhí)行速度的類。

stmt參數(shù)是要測(cè)試的代碼語(yǔ)句(statment);

setup參數(shù)是運(yùn)行代碼時(shí)需要的設(shè)置;

timer參數(shù)是一個(gè)定時(shí)器函數(shù),與平臺(tái)有關(guān)。

timeit.Timer.timeit(number=1000000)

Timer類中測(cè)試語(yǔ)句執(zhí)行速度的對(duì)象方法。number參數(shù)是測(cè)試代碼時(shí)的測(cè)試次數(shù),默認(rèn)為1000000次。方法返回執(zhí)行代碼的平均耗時(shí),一個(gè)float類型的秒數(shù)。

list內(nèi)置操作的時(shí)間復(fù)雜度

dict內(nèi)置操作的時(shí)間復(fù)雜度

Python的內(nèi)置數(shù)據(jù)結(jié)構(gòu)

Python給我們提供了很多現(xiàn)成的數(shù)據(jù)結(jié)構(gòu)類型,這些系統(tǒng)自己定義好的,不需要我們自己去定義的數(shù)據(jù)結(jié)構(gòu)叫做Python的內(nèi)置數(shù)據(jù)結(jié)構(gòu),比如列表、元組、字典。

Python的擴(kuò)展數(shù)據(jù)結(jié)構(gòu)

而有些數(shù)據(jù)組織方式,Python系統(tǒng)里面沒(méi)有直接定義,需要我們自己去定義實(shí)現(xiàn)這些數(shù)據(jù)的組織方式,這些數(shù)據(jù)組織方式稱之為Python的擴(kuò)展數(shù)據(jù)結(jié)構(gòu),比如棧,隊(duì)列等。

算法與數(shù)據(jù)結(jié)構(gòu)的區(qū)別

數(shù)據(jù)結(jié)構(gòu)只是靜態(tài)的描述了數(shù)據(jù)元素之間的關(guān)系。

高效的程序需要在數(shù)據(jù)結(jié)構(gòu)的基礎(chǔ)上設(shè)計(jì)和選擇算法。

程序 = 數(shù)據(jù)結(jié)構(gòu) + 算法

總結(jié):算法是為了解決實(shí)際問(wèn)題而設(shè)計(jì)的,數(shù)據(jù)結(jié)構(gòu)是算法需要處理的問(wèn)題載體

抽象數(shù)據(jù)類型(Abstract Data Type)

抽象數(shù)據(jù)類型(ADT)的含義是指一個(gè)數(shù)學(xué)模型以及定義在此數(shù)學(xué)模型上的一組操作。即把數(shù)據(jù)類型和數(shù)據(jù)類型上的運(yùn)算捆在一起,進(jìn)行封裝。引入抽象數(shù)據(jù)類型的目的是把數(shù)據(jù)類型的表示和數(shù)據(jù)類型上運(yùn)算的實(shí)現(xiàn)與這些數(shù)據(jù)類型和運(yùn)算在程序中的引用隔開(kāi),使它們相互獨(dú)立。

最常用的數(shù)據(jù)運(yùn)算有五種:

插入

刪除

修改

查找

排序

線性表

一個(gè)線性表是某類元素的一個(gè)集合,還記錄著元素之間的一種順序關(guān)系。

根據(jù)線性表的實(shí)際存儲(chǔ)方式,分為兩種實(shí)現(xiàn)模型:

順序表,將元素順序地存放在一塊連續(xù)的存儲(chǔ)區(qū)里,元素間的順序關(guān)系由它們的存儲(chǔ)順序自然表示。

鏈表,將元素存放在通過(guò)鏈接構(gòu)造起來(lái)的一系列存儲(chǔ)塊中。

順序表的兩種存儲(chǔ)方式:

元素內(nèi)置(一體式結(jié)構(gòu)):表里存儲(chǔ)的元素大小固定

元素外置(分離式結(jié)構(gòu)):表里只存儲(chǔ)鏈接

表中存儲(chǔ)的兩個(gè)信息

1.表中的元素集合

2.信息主要包括元素存儲(chǔ)區(qū)的容量和當(dāng)前表中已有的元素個(gè)數(shù)兩項(xiàng)

增加元素

a. 尾端加入元素,時(shí)間復(fù)雜度為O(1)

b. 中間插入,時(shí)間復(fù)雜度為O(n)

刪除元素

a. 刪除表尾元素,時(shí)間復(fù)雜度為O(1)

b. 中間元素刪除,時(shí)間復(fù)雜度為O(n)

Python中的順序表

list和tuple

tuple是不可變類型,即不變的順序表,因此不支持改變其內(nèi)部狀態(tài)的任何操作,而其他方面,則與list的性質(zhì)類似。

list就是一種采用分離式技術(shù)實(shí)現(xiàn)的動(dòng)態(tài)順序表。

鏈表與順序表的對(duì)比

鏈表失去了順序表隨機(jī)讀取的優(yōu)點(diǎn),同時(shí)鏈表由于增加了結(jié)點(diǎn)的指針域,空間開(kāi)銷比較大,但對(duì)存儲(chǔ)空間的使用要相對(duì)靈活。

鏈表與順序表的各種操作復(fù)雜度如下所示:

鏈表的主要耗時(shí)操作是遍歷查找

順序表查找很快,主要耗時(shí)的操作是拷貝覆蓋

3.棧

4.隊(duì)列

代碼:

排序算法(Sorting Algorithm):是一種能將一串?dāng)?shù)據(jù)按照特定順序進(jìn)行排列的一種算法。

穩(wěn)定性

穩(wěn)定性:穩(wěn)定排序算法會(huì)讓原本有相等鍵值的紀(jì)錄維持相對(duì)次序。也就是如果一個(gè)排序算法是穩(wěn)定的,當(dāng)有兩個(gè)相等鍵值的紀(jì)錄R和S,且在原本的列表中R出現(xiàn)在S之前,在排序過(guò)的列表中R也將會(huì)是在S之前。

當(dāng)相等的元素是無(wú)法分辨的,比如像是整數(shù),穩(wěn)定性并不是一個(gè)問(wèn)題。然而,假設(shè)以下的數(shù)對(duì)將要以他們的第一個(gè)數(shù)字來(lái)排序。

(4, 1) (3, 1) (3, 7)(5, 6)

在這個(gè)狀況下,有可能產(chǎn)生兩種不同的結(jié)果,一個(gè)是讓相等鍵值的紀(jì)錄維持相對(duì)的次序,而另外一個(gè)則沒(méi)有:

(3, 1) (3, 7) (4, 1) (5, 6) (維持次序)

(3, 7) (3, 1) (4, 1) (5, 6) (次序被改變)

不穩(wěn)定排序算法可能會(huì)在相等的鍵值中改變紀(jì)錄的相對(duì)次序,但是穩(wěn)定排序算法從來(lái)不會(huì)如此。不穩(wěn)定排序算法可以被特別地實(shí)現(xiàn)為穩(wěn)定。作這件事情的一個(gè)方式是人工擴(kuò)充鍵值的比較,如此在其他方面相同鍵值的兩個(gè)對(duì)象間之比較,(比如上面的比較中加入第二個(gè)標(biāo)準(zhǔn):第二個(gè)鍵值的大小)就會(huì)被決定使用在原先數(shù)據(jù)次序中的條目,當(dāng)作一個(gè)同分決賽。然而,要記住這種次序通常牽涉到額外的空間負(fù)擔(dān)。

常見(jiàn)排序算法效率比較

代碼:

希爾排序(Shell Sort)是插入排序的一種。也稱縮小增量排序,是直接插入排序算法的一種更高效的改進(jìn)版本。希爾排序是非穩(wěn)定排序算法。

希爾排序過(guò)程

希爾排序的基本思想是:將數(shù)組列在一個(gè)表中并對(duì)列分別進(jìn)行插入排序,重復(fù)這過(guò)程,不過(guò)每次用更長(zhǎng)的列(步長(zhǎng)更長(zhǎng)了,列數(shù)更少了)來(lái)進(jìn)行。最后整個(gè)表就只有一列了。將數(shù)組轉(zhuǎn)換至表是為了更好地理解這算法,算法本身還是使用數(shù)組進(jìn)行排序。

例如,假設(shè)有這樣一組數(shù)[ 13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10 ],如果我們以步長(zhǎng)為5開(kāi)始進(jìn)行排序,我們可以通過(guò)將這列表放在有5列的表中來(lái)更好地描述算法,這樣他們就應(yīng)該看起來(lái)是這樣(豎著的元素是步長(zhǎng)組成):

13 14 94 33 82

25 59 94 65 23

45 27 73 25 39

10

然后我們對(duì)每列進(jìn)行排序:

10 14 73 25 23

13 27 94 33 39

25 59 94 65 82

45

將上述四行數(shù)字,依序接在一起時(shí)我們得到:[ 10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45 ]。這時(shí)10已經(jīng)移至正確位置了,然后再以3為步長(zhǎng)進(jìn)行排序:

10 14 73

25 23 13

27 94 33

39 25 59

94 65 82

45

排序之后變?yōu)?#xff1a;

10 14 13

25 23 33

27 25 59

39 65 73

45 94 82

94

最后以1步長(zhǎng)進(jìn)行排序(此時(shí)就是簡(jiǎn)單的插入排序了)

6.二分查找

樹(shù)(英語(yǔ):tree)是一種抽象數(shù)據(jù)類型(ADT)

樹(shù)的術(shù)語(yǔ)

節(jié)點(diǎn)的度:一個(gè)節(jié)點(diǎn)含有的子樹(shù)的個(gè)數(shù)稱為該節(jié)點(diǎn)的度;

樹(shù)的度:一顆樹(shù)中,最大的節(jié)點(diǎn)的度稱為樹(shù)的度;

葉節(jié)點(diǎn)或終端節(jié)點(diǎn):度為零的節(jié)點(diǎn);

父節(jié)點(diǎn):若一個(gè)節(jié)點(diǎn)含有子節(jié)點(diǎn),則這個(gè)節(jié)點(diǎn)稱為其子節(jié)點(diǎn)的父節(jié)點(diǎn);

子節(jié)點(diǎn):一個(gè)節(jié)點(diǎn)含有的子樹(shù)的根節(jié)點(diǎn)稱為該節(jié)點(diǎn)的子節(jié)點(diǎn);

兄弟節(jié)點(diǎn):具有相同父節(jié)點(diǎn)的節(jié)點(diǎn)互相稱為兄弟節(jié)點(diǎn);

節(jié)點(diǎn)的層次:從根節(jié)點(diǎn)開(kāi)始定義起,根為第一層,根的子節(jié)點(diǎn)為第二層,以此類推;

樹(shù)的高度或深度:樹(shù)中節(jié)點(diǎn)的最大層次;

堂兄弟節(jié)點(diǎn):父節(jié)點(diǎn)在同一層次的節(jié)點(diǎn)互為堂兄弟;

節(jié)點(diǎn)的祖先:從根節(jié)點(diǎn)到該節(jié)點(diǎn)所經(jīng)分支上的所有節(jié)點(diǎn);

子孫:以某一節(jié)點(diǎn)為根的子樹(shù)中任一節(jié)點(diǎn)都稱為該節(jié)點(diǎn)的子孫;

森林:由m(m >= 0)顆互不相交的樹(shù)的集合稱為森林;

樹(shù)的種類

無(wú)序樹(shù):樹(shù)中任意節(jié)點(diǎn)的子節(jié)點(diǎn)之間沒(méi)有順序關(guān)系

有序樹(shù):樹(shù)中任意節(jié)點(diǎn)的子節(jié)點(diǎn)之間有順序關(guān)系

二叉樹(shù):每個(gè)節(jié)點(diǎn)最多含有兩個(gè)子樹(shù)

完全二叉樹(shù):除最底層最后一個(gè)外其他必須有子樹(shù)

滿二叉樹(shù):所有葉節(jié)點(diǎn)都在最底層的完全二叉樹(shù)

平衡二叉樹(shù):當(dāng)且僅當(dāng)任何節(jié)點(diǎn)的兩顆子樹(shù)的高度差不大于1的二叉樹(shù)

排序二叉樹(shù):二叉搜索樹(shù)

霍夫曼樹(shù)(用于信息編碼):帶權(quán)路徑最短的二叉樹(shù)

B樹(shù):一種對(duì)讀寫操作進(jìn)行優(yōu)化的自平衡的二叉查找樹(shù),能夠保持?jǐn)?shù)據(jù)有序,擁有杜宇兩個(gè)子樹(shù)

常見(jiàn)的一些樹(shù)的應(yīng)用場(chǎng)景

1.xml,html等,那么編寫這些東西的解析器的時(shí)候,不可避免用到樹(shù)

2.路由協(xié)議就是使用了樹(shù)的算法

3.mysql數(shù)據(jù)庫(kù)索引

4.文件系統(tǒng)的目錄結(jié)構(gòu)

5.所以很多經(jīng)典的AI算法其實(shí)都是樹(shù)搜索,此外機(jī)器學(xué)習(xí)中的decision tree也是樹(shù)結(jié)構(gòu)

二叉樹(shù)的遍歷

深度優(yōu)先遍歷和廣度優(yōu)先遍歷

深度優(yōu)先一般用遞歸,廣度優(yōu)先一般用隊(duì)列。一般情況下能用遞歸實(shí)現(xiàn)的算法大部分也能用堆棧來(lái)實(shí)現(xiàn)。

深度優(yōu)先遍歷

先序遍歷 在先序遍歷中,我們先訪問(wèn)根節(jié)點(diǎn),然后遞歸使用先序遍歷訪問(wèn)左子樹(shù),再遞歸使用先序遍歷訪問(wèn)右子樹(shù)

根節(jié)點(diǎn)->左子樹(shù)->右子樹(shù)

def preorder(self, root):

"""遞歸實(shí)現(xiàn)先序遍歷"""

if root == None:

return

print root.elem

self.preorder(root.lchild)

self.preorder(root.rchild)

中序遍歷 在中序遍歷中,我們遞歸使用中序遍歷訪問(wèn)左子樹(shù),然后訪問(wèn)根節(jié)點(diǎn),最后再遞歸使用中序遍歷訪問(wèn)右子樹(shù)

左子樹(shù)->根節(jié)點(diǎn)->右子樹(shù)

def inorder(self, root):

"""遞歸實(shí)現(xiàn)中序遍歷"""

if root == None:

return

self.inorder(root.lchild)

print root.elem

self.inorder(root.rchild)

后序遍歷 在后序遍歷中,我們先遞歸使用后序遍歷訪問(wèn)左子樹(shù)和右子樹(shù),最后訪問(wèn)根節(jié)點(diǎn)

左子樹(shù)->右子樹(shù)->根節(jié)點(diǎn)

def postorder(self, root):

"""遞歸實(shí)現(xiàn)后續(xù)遍歷"""

if root == None:

return

self.postorder(root.lchild)

self.postorder(root.rchild)

print root.elem

前序和后序在本質(zhì)上都是將父節(jié)點(diǎn)與子結(jié)點(diǎn)進(jìn)行分離,但并沒(méi)有指明左子樹(shù)和右子樹(shù)的能力,因此得到這兩個(gè)序列只能明確父子關(guān)系,而不能確定一個(gè)二叉樹(shù)。

由二叉樹(shù)的中序和前序遍歷序列可以唯一確定一棵二叉樹(shù) ,由前序和后序遍歷則不能唯一確定一棵二叉樹(shù)

由二叉樹(shù)的中序和后序遍歷序列可以唯一確定一棵二叉樹(shù),由前序和后序遍歷則不能唯一確定一棵二叉樹(shù)

總結(jié)

以上是生活随笔為你收集整理的python structure_GitHub - CYZYZG/Data_Structure_with_Python: 这是我在学习《基于Python的数据结构》的时候的笔记与代码...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。