數(shù)據(jù)結(jié)構(gòu)與算法系列3
寫在前面
前面兩章講了鏈表和動(dòng)態(tài)數(shù)組,我們這章來從內(nèi)存的角度的來講講二者的區(qū)別
什么是內(nèi)存
寫在前面:
由于本章是從內(nèi)存的角度來講述數(shù)組與鏈表,所以我們先來講講內(nèi)存
內(nèi)存概述
內(nèi)存是計(jì)算機(jī)的重要部件之一。它是外存與CPU進(jìn)行溝通的橋梁,計(jì)算機(jī)中所有程序的運(yùn)行都在內(nèi)存中進(jìn)行。內(nèi)存性能的強(qiáng)弱影響計(jì)算機(jī)整體發(fā)揮的水平。內(nèi)存(Memory)也稱內(nèi)存儲(chǔ)器和主存儲(chǔ)器,它用于暫時(shí)存放CPU中的運(yùn)算數(shù)據(jù),與硬盤等外部存儲(chǔ)器交換的數(shù)據(jù)。只要計(jì)算機(jī)開始運(yùn)行,操作系統(tǒng)就會(huì)把需要運(yùn)算的數(shù)據(jù)從內(nèi)存調(diào)到CPU中進(jìn)行運(yùn)算。當(dāng)運(yùn)算完成,CPU將結(jié)果傳送出來。內(nèi)存的運(yùn)行也決定計(jì)算機(jī)整體運(yùn)行快慢的程度。內(nèi)存條由內(nèi)存芯片、電路板、金手指等部分組成。
內(nèi)存工作原理
比如我們?nèi)タ捡{照,考駕照的地方有一個(gè)寄存柜,你需要將你的東西寄存到寄存柜里
假設(shè)每個(gè)柜子只可以放一樣?xùn)|西,你有兩樣?xùn)|西需要寄存,因此需要兩個(gè)寄存柜
然后你就可以將你的兩樣?xùn)|西寄存到箱子里
然后你就可以放心的去考駕照了,等考好了再到對(duì)應(yīng)的箱子里取出自己的物品即可,這大致就是計(jì)算機(jī)內(nèi)存的工作原理,計(jì)算機(jī)像是很多抽屜的集合,每個(gè)抽屜都有地址,就像下面一樣劃分成一個(gè)個(gè)區(qū)塊,一個(gè)個(gè)地址
需要將數(shù)據(jù)存儲(chǔ)到內(nèi)存時(shí),你請(qǐng)求計(jì)算機(jī)提供存儲(chǔ)空間,計(jì)算機(jī)給你一個(gè)存儲(chǔ)地址。需要存儲(chǔ)多項(xiàng)數(shù)據(jù)。有兩種基本方式---數(shù)組和鏈表。他們并非都適用與所有場景。
數(shù)組在內(nèi)存中的分布
數(shù)組再內(nèi)存中是連續(xù)分布的,什么是連續(xù)分布呢,就拿上面的寄存柜來說,比如寄存柜有100個(gè)柜子,你有四個(gè)東西要寄存,一個(gè)柜子只能放一個(gè)東西,所以你要四個(gè)柜子,連續(xù)分布就是只這四個(gè)柜子要一個(gè)柜子挨著一個(gè)柜子連在一起,需要連號(hào),比如1234,5678等等
數(shù)字代表寄存的物品標(biāo)號(hào)
這種方式的優(yōu)缺點(diǎn)是什么呢?
我們?cè)賮砼e一個(gè)例子
比如我們?nèi)ソM團(tuán)看電影,看電影的時(shí)候一共有十個(gè)人,為了保證10個(gè)人能坐在一起,必須提前訂好10個(gè)連續(xù)的位置。這樣的好處就是能保證10個(gè)人可以在一起。但是這樣的缺點(diǎn)是,如果來的人不夠10個(gè),那么剩下的位置就浪費(fèi)了。如果臨時(shí)有多來了個(gè)人,那么10個(gè)就不夠用了,這時(shí)可能需要將第11個(gè)位置上的人挪走,或者是他們11個(gè)人重新去找一個(gè)11連坐的位置,效率都很低。如果沒有找到符合要求的作為,那么就沒法坐了。
缺點(diǎn)
人來在計(jì)算機(jī)中就是插入數(shù)據(jù),人走在計(jì)算機(jī)中就是刪除數(shù)據(jù)。而數(shù)組方式存放數(shù)據(jù),插入數(shù)據(jù)和刪除數(shù)據(jù)效率低,插入數(shù)據(jù)時(shí),這個(gè)位置后面的數(shù)據(jù)在內(nèi)存中都要向后移。刪除數(shù)據(jù)時(shí),這個(gè)數(shù)據(jù)后面的數(shù)據(jù)都要往前移動(dòng)。 比如原來去了5個(gè)人,然后后來又去了一個(gè)人要坐在第三個(gè)位置上,那么第三個(gè)到第五個(gè)都要往后移動(dòng)一個(gè)位子,將第三個(gè)位置留給新來的人。 當(dāng)這個(gè)人走了的時(shí)候,因?yàn)樗麄円B在一起的,所以他后面幾個(gè)人要往前移動(dòng)一個(gè)位置,把這個(gè)空位補(bǔ)上。
預(yù)留座位
對(duì)于這種位置不夠的缺點(diǎn)我們可以通過"預(yù)留座位的方式"來解決,即即使你們只有十個(gè)人去看電影,為了防止有人突然拖家?guī)Э冢瑢?dǎo)致位置不夠的情況,為了以防萬一你就事先買了十五張電影票。一旦有人來了就有位置做了。在計(jì)算機(jī)中我們?yōu)榱朔乐箶?shù)組溢出,也可以使用這種方式,即申請(qǐng)一個(gè)比預(yù)期大的數(shù)組,來防止數(shù)組不夠大,存儲(chǔ)不了數(shù)據(jù)的情況。但這種"預(yù)留座位"的方式也會(huì)導(dǎo)致內(nèi)存空間的浪費(fèi)
優(yōu)點(diǎn)
隨機(jī)讀取效率很高。因?yàn)閿?shù)組是連續(xù)的,知道每一個(gè)數(shù)據(jù)的內(nèi)存地址,可以直接找到給地址的數(shù)據(jù)。
并且不利于擴(kuò)展,數(shù)組定義的空間不夠時(shí)要重新定義數(shù)組。(剛剛講的十個(gè)座位,多來了一個(gè)人,你就只能重新申請(qǐng)空間定義一個(gè)大于11的數(shù)組)
鏈表在內(nèi)存中的分布
數(shù)組再內(nèi)存中是非連續(xù)分布的,什么是非連續(xù)分布呢,就拿上面的寄存柜來說,比如寄存柜有100個(gè)柜子,你有四個(gè)東西要寄存,一個(gè)柜子只能放一個(gè)東西,所以你要四個(gè)柜子,非連續(xù)分布就是隨便在寄存柜中找四個(gè)柜子就可以了,不需要連號(hào),比如1589,2489等等都可以
數(shù)字代表寄存的物品標(biāo)號(hào)
優(yōu)缺點(diǎn)
在內(nèi)存中可以存在任何地方,不要求連續(xù)。 在電影院幾個(gè)人可以隨便坐。比如十個(gè)人去看電影,這十個(gè)人可以在電影院隨便找十個(gè)位置坐下。不需要十個(gè)人坐在一起,這十個(gè)人每個(gè)人都記住下一個(gè)人的位置號(hào),這樣到時(shí)候找人也就不會(huì)找不到了
在計(jì)算機(jī)中也一樣的道理,每一個(gè)數(shù)據(jù)都保存了下一個(gè)數(shù)據(jù)的內(nèi)存地址,通過這個(gè)地址找到下一個(gè)數(shù)據(jù)。 第一個(gè)人知道第二個(gè)人的座位號(hào),第二個(gè)人知道第三個(gè)人的座位號(hào)……
優(yōu)點(diǎn)
增加數(shù)據(jù)和刪除數(shù)據(jù)很容易。 再來個(gè)人可以隨便坐,比如來了個(gè)人要做到第三個(gè)位置,那他只需要把自己的位置告訴第二個(gè)人,然后問第二個(gè)人拿到原來第三個(gè)人的位置就行了。其他人都不用動(dòng)。
不指定大小,擴(kuò)展方便。鏈表大小不用定義,數(shù)據(jù)隨意增刪。
缺點(diǎn)
查找數(shù)據(jù)時(shí)效率低,因?yàn)椴痪哂须S機(jī)訪問性,所以訪問某個(gè)位置的數(shù)據(jù)都要從第一個(gè)數(shù)據(jù)開始訪問,然后根據(jù)第一個(gè)數(shù)據(jù)保存的下一個(gè)數(shù)據(jù)的地址找到第二個(gè)數(shù)據(jù),以此類推。 要找到第三個(gè)人,必須從第一個(gè)人開始問起。
小總結(jié)
數(shù)組的優(yōu)點(diǎn)
- 隨機(jī)訪問性強(qiáng)
- 查找速度快
數(shù)組的缺點(diǎn)
- 插入和刪除效率低
- 可能浪費(fèi)內(nèi)存
- 內(nèi)存空間要求高,必須有足夠的連續(xù)內(nèi)存空間。
- 數(shù)組大小固定,不能動(dòng)態(tài)拓展
鏈表的優(yōu)點(diǎn)
- 插入刪除速度快
- 內(nèi)存利用率高,不會(huì)浪費(fèi)內(nèi)存
- 大小沒有固定,拓展很靈活。
鏈表的缺點(diǎn)
- 不能隨機(jī)查找,必須從第一個(gè)開始遍歷,查找效率低
- | 數(shù)組 | 鏈表 |
---|---|---|
讀取 | O(1) | O(n) |
插入 | O(n) | O(1) |
刪除 | O(n) | O(1) |
應(yīng)用場景
數(shù)組應(yīng)用場景:
數(shù)據(jù)比較少;經(jīng)常做的運(yùn)算是按序號(hào)訪問數(shù)據(jù)元素;數(shù)組更容易實(shí)現(xiàn),任何高級(jí)語言都支持;構(gòu)建的線性表較穩(wěn)定。
鏈表應(yīng)用場景:
對(duì)線性表的長度或者規(guī)模難以估計(jì);頻繁做插入刪除操作;構(gòu)建動(dòng)態(tài)性比較強(qiáng)的線性表。