www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > 技術(shù)學(xué)院 > 技術(shù)前線
[導(dǎo)讀]數(shù)據(jù)結(jié)構(gòu)是抽象的概念,沒有語言之別,就像是設(shè)計模式一樣,是一種抽象的思想,用任何語言的代碼都能構(gòu)建出來。而我們的python中的字符串,列表,字典,元祖,集合都是基本數(shù)據(jù)類型,他們是依附于語言存在的,不同的語言有不同的基本數(shù)據(jù)類型。

線性表就是數(shù)據(jù)排成像一條線一樣的結(jié)構(gòu)。每個線性表上的數(shù)據(jù)最多只有前和后兩個方向。其實除了數(shù)組,鏈表、隊列、棧等也是線性表結(jié)構(gòu)。而與它相對立的概念是非線性表,比如二叉樹、堆、圖等。

所謂的數(shù)據(jù)結(jié)構(gòu)就是表示數(shù)據(jù)之間的關(guān)系。這些數(shù)據(jù)結(jié)構(gòu)中的每一個元素都是緊密相連的,不能有空隙。

數(shù)據(jù)結(jié)構(gòu)是抽象的概念,沒有語言之別,就像是設(shè)計模式一樣,是一種抽象的思想,用任何語言的代碼都能構(gòu)建出來。而我們的python中的字符串,列表,字典,元祖,集合都是基本數(shù)據(jù)類型,他們是依附于語言存在的,不同的語言有不同的基本數(shù)據(jù)類型。

在二進制下的數(shù)據(jù)類型所占的位數(shù):

int8位

longint16位

shortint4位

char---assic8位;gbk16位;utf-8,24位;unicode32位;

float--占4個字節(jié),即32位,具體分布如下:1bit(符號位,即正負號),8bit(指數(shù)位),23bit(尾數(shù)位)。

數(shù)組

數(shù)組是一維圖形。

數(shù)組是定長,所謂的定長就是在創(chuàng)建之初就需要告訴解釋器它的長度,而我們的列表是不定長的,所謂的不定長就是我們創(chuàng)建了一個列表,我們?nèi)庋劭吹降目赡苓@個列表只有3個元素或者我們就干脆創(chuàng)建一個空列表,但是在內(nèi)部實現(xiàn)的時候解釋器給這個列表一個初始長度,假設(shè)這個長度是20,然后我們對這個我們所創(chuàng)建了列表進行增刪改查的時候,這個列表的長度就會發(fā)生變化,然后發(fā)生變化的過程中,系統(tǒng)內(nèi)部就把這個列表一開始的所有數(shù)據(jù)給拷貝下來,然后根據(jù)你增刪改查的結(jié)果對列表進行擴大或者縮小。

數(shù)組中的數(shù)據(jù)類型必須要保持一致,一個數(shù)組中只能存一種數(shù)據(jù)類型,所謂的數(shù)據(jù)類型就是:整數(shù)int,小數(shù)float,字符串char這些類型。列表里面存的數(shù)據(jù)類型是不一樣的,但是在解釋器內(nèi)部,這些個不同的數(shù)據(jù)類型都是被python實例化出來的一個個對象,然后在列表中存的都是這些對象的一個個的地址指針。

數(shù)組可以通過索引取值,時間復(fù)雜度是O1.(O1這個時間復(fù)雜度跟數(shù)組的規(guī)模是沒有差別的,不論是多長的數(shù)組,它的時間復(fù)雜度都是O1.而On的話,這個n可以是任何常數(shù),比如可以是20、300、5000等等,都遠遠沒有O1快)它的取值原理是因為數(shù)組存的是同一種數(shù)據(jù)類型,而數(shù)據(jù)類型都是固定長度的,所以可以通過長度取值。比如這里有一個數(shù)組A,它存的都是整數(shù)類型,第一個元素的地址假設(shè)是0110,那么我們要獲取這個A數(shù)組中的第4個元素,只需要通過第一個元素的地址加上(4-1)*8=24,即0110+24=0134,就是第4個元素的地址,然后就能直接很快地拿到這個元素,內(nèi)存地址都是連續(xù)的。這就是它取值快的地方。但是它有弊端,我們的數(shù)組中每一個元素都是緊挨著的,打一個比方,算盤,它的每一根柱子上都是一串算珠,我們把這個算盤立起來的時候,算珠都會垂直落到底部,我們假設(shè)拆掉一個柱子上的一個算珠,那么這個算珠上面的算珠會依次降落到下一個算珠的位置上,然后這個柱子的算珠整體高度就會下降一個算珠的高度,或者我們增加一個算珠,我們所增加的這個算珠上面的所有算珠都會上升到上一個算珠的位置上,因為算珠之間不能有空隙,要一個個緊緊挨著。我們的數(shù)組就類似這樣的情況,當(dāng)我們要在數(shù)組中插入一個值的時候,我們所插入的這個位置,后面的所有元素都要依次往后挪一個元素的位置,就像我們給算盤增加算珠一樣,在增加的位置上的每一上面的算珠都要往上挪一個算珠的位置;同理,如果要刪除一個數(shù)組中的元素的話,那么這個被刪除的元素的位置就空出來了,然后因為我們的數(shù)組里面的元素都是緊挨著的,所以這個被刪除的元素后面的元素都會依次往前挪一個元素的位置,就像我們的算盤上取掉一個算珠,這個算珠的上面每一個算珠都要往下降一個算珠的位置,就是這個道理。所以如果刪除或者是插入一個數(shù)組中的中間元素的話,它后面的所有元素都需要挪動位置,這里就沒有取值那么便捷了,時間復(fù)雜度就會增加,但是,如果是增加或者是刪除最后一個元素就不會涉及到其他元素的操作,這里就不存在時間復(fù)雜度的增加問題了。

堆棧

堆棧也是一維圖形。

我們想象一下一個裝羽毛球的球桶,它的直徑就是羽毛球的羽毛那一端所圍成的圓形的直徑,這樣一個個羽毛球放進去剛好卡在桶壁內(nèi),沒有多余空隙,以免晃動中產(chǎn)生摩擦帶來不必要的損耗。假設(shè)這個球桶只有一個口,另一段是封死的,這個時候假設(shè)這個球桶是空的,我們把羽毛球一個個依次放進去的時候,只能從這個口放進去,然后也只能從這個口拿出來,也就是先進后出,后進先出。

在這個堆棧中我們只研究棧頂,這個棧頂?shù)奈恢镁褪俏覀兊亩褩Uw高度。也就是說在這個羽毛球桶中,最上面的這個羽毛球在刻度4處,這個球桶中就有4個球,此時我們拿出去一個球,這個球桶中最上面的這個球就在3這個刻度上了,此時球桶中就有3個球,這個球桶中最上面的球就被我們標(biāo)記為棧頂。實現(xiàn)一個堆棧的方式就是一個變量+一個數(shù)組。這個變量指向這個數(shù)組中的最后一個元素,比如這個數(shù)組中有8個元素,這個變量指向8,這個堆棧就有8個元素,棧頂就是8。

堆棧組成可以用列表實現(xiàn),也可以用數(shù)組實現(xiàn),如果用列表的話就可以存放不同的數(shù)據(jù)類型。

需要附上堆棧的代碼實現(xiàn),以上僅僅是概念性的原理。代碼需要有一個類,類里面有兩個方法,入棧和出棧,入棧時需要考慮到棧的大小,棧滿時不可入,同時,出棧也要考慮到??諘r不能出。

隊列

隊列也是一維圖形。

隊列不同于堆棧有一個口,進出都是它(我們叫做出入耦合),隊列不一樣,它有2個口,一個單獨的出口,一個單獨的入口(我們叫做出入分離)。同向時如果出入口重合,則隊列為空,反向時如果出入口重合,則隊列為滿。我們在隊列問題中,僅僅考慮兩個點,入口和出口,而且這兩個要分開考慮,不能想得過于復(fù)雜。所以按照堆棧的實現(xiàn)方式,隊列的實現(xiàn)就是兩個變量+數(shù)組。

隊列同上,用數(shù)組和列表都能實現(xiàn)。

鏈表

鏈表也是一維圖形。

鏈表中的每一個元素都會標(biāo)記一個尾部指向,這個指向是指向下一個元素,然后每一個元素之間用尾部彼此相連,所謂鏈表就像鐵鏈一樣,彼此之間緊密相扣,形成一條鏈條。鏈表是沒有大小的,不同于數(shù)組,堆棧和隊列。

雙向鏈表就是不僅會標(biāo)記尾部指向,還會有頭部指向,一條鏈表中的任意一個元素拿出來,它有頭部指向,指向上一個元素,還有尾部指向,指向下一個元素,這就是雙向鏈表。

鏈表分單向和雙向,兩種。彼此之間不能混合,單向和單向組合,雙向和雙向組合。循環(huán)鏈表,就是尾項指向頭項,首位相連形成一個圓,就是循環(huán)鏈表,也就沒有頭尾之分。

鏈表的增刪改查,跟數(shù)組比起來就要快很多了,比如我們要刪除一個鏈表中的元素,就需要把這個元素的上一個元素的尾部指向指向到這個元素的下一個元素的尾部指向即可,就像是把這個鏈條上的一個鏈環(huán)拿掉就把這個鏈條分成了兩截,然后把這個斷開的部分重新鏈接上即可,比如是abcd的鏈條,把c拿掉,就讓b和d鏈接上即可,不會涉及到更多元素的操作,比起數(shù)組就方便很多。但是有一點弊端,就是數(shù)組取值,是通過索引取值,會很快,而鏈表如果要取值,就需要從鏈頭開始找依次去找到那個值然后返回,這樣就會慢很多,如果剛好要找的那個值是鏈尾,那么就需要遍歷整個鏈表。時間復(fù)雜度是O(n)。

一、數(shù)組

數(shù)組(Array)是一種線性表數(shù)據(jù)結(jié)構(gòu)。它用一組連續(xù)的內(nèi)存空間,來存儲一組具有相同類型的數(shù)據(jù)。

數(shù)組可以根據(jù)下標(biāo)隨機訪問,計算機根據(jù)尋址公式可以快速查找下標(biāo)為i的元素:

a[i]_address = base_address + i() * data_type_size

即下標(biāo)為i的元素地址=數(shù)組首地址+下標(biāo) i 乘以 數(shù)據(jù)類型大小。例如數(shù)組中存儲的是 int 類型數(shù)據(jù)data_type_size 就為 4 個字節(jié)。數(shù)組要求連續(xù)的內(nèi)存空間,所以想在數(shù)組中刪除、插入一個數(shù)據(jù),為了保證連續(xù)性,就需要做大量的數(shù)據(jù)搬移工作。

小結(jié):數(shù)組用一塊連續(xù)的內(nèi)存空間,來存儲相同類型的一組數(shù)據(jù),最大的特點就是支持隨機訪問O(1),但插入、刪除操作比較低效,平均情況時間復(fù)雜度為 O(n)。

二、鏈表(Linked list)

鏈表不需要像數(shù)組一樣需要一塊連續(xù)的內(nèi)存空間,它通過“指針”將一組零散的內(nèi)存塊串聯(lián)起來使用。

常見的鏈表結(jié)構(gòu)有:單鏈表、雙向鏈表和循環(huán)鏈表。通常第一個結(jié)點叫作頭結(jié)點,把最后一個結(jié)點叫作尾結(jié)點,頭結(jié)點用來記錄鏈表的基地址。

1、單鏈表:每個鏈表的結(jié)點除了存儲數(shù)據(jù)之外,還有一個后繼指針 next記錄下一個結(jié)點的地址。尾結(jié)點指向一個空地址 NULL。

2、循環(huán)鏈表:循環(huán)鏈表是特殊的單鏈表。循環(huán)鏈表的尾結(jié)點指針是指向鏈表的頭結(jié)點。

3、雙向鏈表:每個結(jié)點不止有一個后繼指針 next 指向后面的結(jié)點,還有一個前驅(qū)指針 prev 指向前面的結(jié)點。

針對鏈表的插入和刪除操作,我們只需要考慮相鄰結(jié)點的指針改變,所以對應(yīng)的時間復(fù)雜度是 O(1)。因為鏈表中的數(shù)據(jù)并非連續(xù)存儲的,想隨機訪問第 k 個元素,無法像數(shù)組那樣通過尋址公式就能直接計算出對應(yīng)的內(nèi)存地址,而是需要根據(jù)指針一個結(jié)點一個結(jié)點地依次遍歷,直到找到相應(yīng)的結(jié)點。

小結(jié):鏈表是內(nèi)存不連續(xù)的,通過“指針”將零散的內(nèi)存塊串聯(lián)起來使用的。鏈表的插入和刪除操作比較快都快O(1),隨機訪問的性能沒有數(shù)組好O(n),編寫代碼時注意邊界條件,對插入第一個結(jié)點和刪除最后一個結(jié)點的情況進行特殊處理。

三、棧

棧的特點:后進先出。棧主要包含兩個操作,入棧 push()和出棧 pop(),也就是在棧頂插入一個數(shù)據(jù)和從棧頂刪除一個數(shù)據(jù)。

數(shù)組實現(xiàn)的棧,我們叫作順序棧,支持動態(tài)擴容。用鏈表實現(xiàn)的棧,我們叫作鏈式棧。

棧的應(yīng)用:

1、函數(shù)調(diào)用棧

操作系統(tǒng)給每個線程分配了一塊獨立的內(nèi)存空間,用來存儲函數(shù)調(diào)用時的臨時變量。每進入一個函數(shù),就會將臨時變量作為一個棧幀入棧,當(dāng)被調(diào)用函數(shù)執(zhí)行完成,返回之后,將這個函數(shù)對應(yīng)的棧幀出棧

eg:

int main() {

int a = 1;

int ret = 0;

int res = 0;

ret = add(3, 5);

res = a + ret;

printf("%d", res);

reuturn 0;

}

int add(int x, int y) {

int sum = 0;

sum = x + y;

return sum;

}

函數(shù)棧里出棧、入棧的操作:

2、表達式求值

eg:3+5*8-6。

實際上,編譯器就是通過兩個棧來實現(xiàn)的。其中一個保存操作數(shù)的棧,另一個是保存運算符的棧。我們從左向右遍歷表達式,當(dāng)遇到數(shù)字,我們就直接壓入操作數(shù)棧;當(dāng)遇到運算符,就與運算符棧的棧頂元素進行比較。如果比運算符棧頂元素的優(yōu)先級高,就將當(dāng)前運算符壓入棧;如果比運算符棧頂元素的優(yōu)先級低或者相同,從運算符棧中取棧頂運算符,從操作數(shù)棧的棧頂取 2 個操作數(shù),然后進行計算,再把計算完的結(jié)果壓入操作數(shù)棧,繼續(xù)比較。

小結(jié):棧是一種“操作受限”的線性表,只允許在一端插入和刪除數(shù)據(jù)即入棧和出棧,只需要一個棧頂指針。后進者先出,先進者后出。典型應(yīng)用場景函數(shù)調(diào)用,表達式求值也需要理解。入棧、出棧的時間復(fù)雜度都為 O(1)。

四、隊列

隊列的特點:先進先出。主要包含兩個操作,入隊enqueue(),放一個數(shù)據(jù)到隊列尾部;出隊 dequeue(),從隊列頭部取一個元素。用數(shù)組實現(xiàn)的隊列叫作順序隊列,用鏈表實現(xiàn)的隊列叫作鏈式隊列。

隊空和隊滿的判定條件:隊滿的判斷條件是 tail == n,隊空的判斷條件是 head == tail。

在數(shù)組實現(xiàn)隊列的時候,會有數(shù)據(jù)搬移操作,要想解決數(shù)據(jù)搬移的問題,我們就需要像環(huán)一樣的循環(huán)隊列。循環(huán)隊列當(dāng)隊滿時,(tail+1)%n=head。其中最后tail 指向的位置實際上是沒有存儲數(shù)據(jù)的。所以,循環(huán)隊列會浪費一個數(shù)組的存儲空間。

小結(jié):隊列也是一種“操作受限”的線性表,先進者先出,對應(yīng)入隊和出隊,隊列需要兩個指針:一個是 head 指針,指向隊頭;一個是 tail 指針,指向隊尾。注意隊空和隊滿的判定條件,典型應(yīng)用場景如循環(huán)隊列、阻塞隊列、并發(fā)隊列、線程池。

五、遞歸

1、遞歸需要滿足的三個條件:

一個問題的解可以分解為幾個子問題的解

這個問題與分解之后的子問題,除了數(shù)據(jù)規(guī)模不同,求解思路完全一樣。

存在遞歸終止條件。

2、如何編寫遞歸代碼?

最關(guān)鍵的是寫出遞推公式,找到終止條件。

3、為什么遞歸代碼容易造成堆棧溢出呢?

函數(shù)調(diào)用會使用棧來保存臨時變量。每調(diào)用一個函數(shù),都會將臨時變量封裝為棧幀壓入內(nèi)存棧,等函數(shù)執(zhí)行完成返回時,才出棧。系統(tǒng)?;蛘咛摂M機棧空間一般都不大。如果遞歸求解的數(shù)據(jù)規(guī)模很大,調(diào)用層次很深,一直壓入棧,就會有堆棧溢出的風(fēng)險。

4、那如何避免出現(xiàn)堆棧溢出呢?

我們可以通過在代碼中限制遞歸調(diào)用的最大深度的方式來解決這個問題。

為了避免重復(fù)計算,我們可以通過一個數(shù)據(jù)結(jié)構(gòu)(比如散列表)來保存已經(jīng)求解過的 f(k)。當(dāng)遞歸調(diào)用到 f(k)時,先看下是否已經(jīng)求解過了。如果是,則直接從散列表中取值返回,不需要重復(fù)計算。

小結(jié):遞歸不算數(shù)據(jù)結(jié)構(gòu)但是一種應(yīng)用非常廣泛的編程技巧,注意使用遞歸需滿足的條件以及如何找出遞歸公式和終止條件,避免死循環(huán),編碼時注意避免堆棧溢出和重復(fù)計算。 典型應(yīng)用如 DFS 深度優(yōu)先搜索、前中后序二叉樹遍歷,斐波那契數(shù)列。

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動電源

在工業(yè)自動化蓬勃發(fā)展的當(dāng)下,工業(yè)電機作為核心動力設(shè)備,其驅(qū)動電源的性能直接關(guān)系到整個系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動勢抑制與過流保護是驅(qū)動電源設(shè)計中至關(guān)重要的兩個環(huán)節(jié),集成化方案的設(shè)計成為提升電機驅(qū)動性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機 驅(qū)動電源

LED 驅(qū)動電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個照明設(shè)備的使用壽命。然而,在實際應(yīng)用中,LED 驅(qū)動電源易損壞的問題卻十分常見,不僅增加了維護成本,還影響了用戶體驗。要解決這一問題,需從設(shè)計、生...

關(guān)鍵字: 驅(qū)動電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動電源的公式,電感內(nèi)電流波動大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計 驅(qū)動電源

電動汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動汽車的核心技術(shù)之一是電機驅(qū)動控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機驅(qū)動系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動汽車的動力性能和...

關(guān)鍵字: 電動汽車 新能源 驅(qū)動電源

在現(xiàn)代城市建設(shè)中,街道及停車場照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進步,高亮度白光發(fā)光二極管(LED)因其獨特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動電源 LED

LED通用照明設(shè)計工程師會遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動電源的電磁干擾(EMI)問題成為了一個不可忽視的挑戰(zhàn)。電磁干擾不僅會影響LED燈具的正常工作,還可能對周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動電源

開關(guān)電源具有效率高的特性,而且開關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機重量也有所下降,所以,現(xiàn)在的LED驅(qū)動電源

關(guān)鍵字: LED 驅(qū)動電源 開關(guān)電源

LED驅(qū)動電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動電源
關(guān)閉