扩容是元素还是数组_数组是如何随机访问元素?数组下标为什么从0开始,而不是1?...
數(shù)組如何實(shí)現(xiàn)隨機(jī)訪問(wèn)元素
什么是數(shù)組?
數(shù)組(Array)是一種線性表數(shù)據(jù)結(jié)構(gòu),它用一組連續(xù)的內(nèi)存空間,來(lái)存儲(chǔ)相同類型的數(shù)據(jù)。
什么是線性表(Linear List)?
線性表就是數(shù)據(jù)排成一條線一樣的結(jié)構(gòu),每個(gè)線性表的數(shù)據(jù)最多只有前后兩個(gè)方向。
例如:數(shù)組,鏈表,隊(duì)列,棧 等都是線性表結(jié)構(gòu)。
什么是非線性表?
例如:二叉樹(shù),堆,圖,等,是非線性表,是因?yàn)?#xff0c;在非線性表中,數(shù)據(jù)之間并不是簡(jiǎn)單的前后關(guān)系。
數(shù)組是如何隨機(jī)訪問(wèn)數(shù)組元素?
數(shù)組是如何實(shí)現(xiàn)根據(jù)下標(biāo)隨機(jī)訪問(wèn)數(shù)組元素的嗎?
例如: int[]a=newint[10]
1,計(jì)算機(jī)給數(shù)組a[10],分配了一組連續(xù)的內(nèi)存空間。
2,比如內(nèi)存塊的首地址為 base_address=1000。
3,當(dāng)計(jì)算給每個(gè)內(nèi)存單元分配一個(gè)地址,計(jì)算機(jī)通過(guò)地址來(lái)訪問(wèn)數(shù)據(jù)。當(dāng)計(jì)算機(jī)需要訪問(wèn)數(shù)組的某個(gè)元素的時(shí)候,會(huì)通過(guò)一個(gè)尋址公式來(lái)計(jì)算存儲(chǔ)的內(nèi)存地址。
公式如下:
a[i]_address = base_address + i * data_type_sizearr[i] 首地址 = 數(shù)組內(nèi)存塊首地址 + 數(shù)據(jù)類型大小 * i ,其中i為偏移量。
baseaddress:內(nèi)存塊的首地址。datatype_size:數(shù)組中每個(gè)元素的大小,比如每個(gè)元素大小是4個(gè)字節(jié)。
1,數(shù)組使用二分法查找元素,時(shí)間復(fù)雜度是O(logn)。
2,根據(jù)下標(biāo)隨機(jī)訪問(wèn)的時(shí)間復(fù)雜度是O(1)。
低效的“插入”和“刪除”
插入
插入:從最好O(1) 最壞O(n) 平均O(n)
什么時(shí)候會(huì)是O(1)?
數(shù)組若無(wú)序,插入新的元素時(shí),可以將第K個(gè)位置元素移動(dòng)到數(shù)組末尾,把新的元素,插入到第k個(gè)位置,此處復(fù)雜度為O(1)。
例如:a[10] 數(shù)組存儲(chǔ)了5個(gè)元素: A B C D E
我們現(xiàn)在需要將元素 x 插入到第 3 個(gè)位置。我們只需要將 c 放入到 a[5],將 a[2] 賦值為 x 即可。
最后,數(shù)組中的元素如下: A,C,X,D,E,C。
什么時(shí)候會(huì)是最壞O(n)?
從數(shù)組開(kāi)頭插入數(shù)據(jù),所有的數(shù)據(jù)往后移一位,情況最差,時(shí)間復(fù)雜度為O(n) 。
每一位插入的概率一樣,所以平均時(shí)間復(fù)雜度為 (1+2+...+n)/n=(1+n)/2=O(n)。
刪除
刪除:從最好O(1) 最壞O(n) 平均O(n)
和插入數(shù)據(jù)類似,如果我們要?jiǎng)h除 K 個(gè)位置的數(shù)據(jù),要保證內(nèi)存的連續(xù)性,我們需要搬移 K 位置后的所有數(shù)據(jù)往前移動(dòng)一位。
什么時(shí)候會(huì)是O(1)?
刪除開(kāi)頭的數(shù)據(jù)
什么時(shí)候會(huì)是最壞O(n)?
同數(shù)組插入的原理類似
數(shù)組如何提高效率?
將多次刪除操作中集中在一起執(zhí)行,可以先記錄已經(jīng)刪除的數(shù)據(jù),但是不進(jìn)行數(shù)據(jù)遷移,而僅僅是記錄,當(dāng)發(fā)現(xiàn)沒(méi)有更多空間存儲(chǔ)時(shí),再執(zhí)行真正的刪除操作,這樣減少數(shù)據(jù)搬移次數(shù)節(jié)省耗時(shí)。
這也是跟 JVM 標(biāo)記清除垃圾回收算法的核心思想相似。
標(biāo)記-整理垃圾回收算法。
在垃圾收集時(shí)此算法分為“標(biāo)記”、“清除”兩個(gè)階段,先標(biāo)記出需要回收的對(duì)象,再統(tǒng)一清除標(biāo)記的對(duì)象。清除之后會(huì)產(chǎn)生大量不連續(xù)的內(nèi)存碎片。
標(biāo)記-整理垃圾回收算法
在標(biāo)記完成之后讓所有存活的對(duì)象都向一端移動(dòng),然后直接清理掉邊界以外的內(nèi)存。
用數(shù)組還是容器?
數(shù)組先指定容器大小,容器ArrayList可以動(dòng)態(tài)擴(kuò)容,并且封裝了好多方法,一旦超過(guò)存儲(chǔ)容量,擴(kuò)容時(shí)比較耗時(shí),因?yàn)樯婕皟?nèi)存申請(qǐng)和數(shù)據(jù)復(fù)制搬移到擴(kuò)容后的數(shù)組。
1,如果已知數(shù)據(jù)大小,且涉及的數(shù)據(jù)操作比較簡(jiǎn)單,可以用數(shù)組。
2,比如已知 1 萬(wàn)條數(shù)據(jù)要存入 ArrayList,我們就可以事先指定容器大小。
例如下代碼,就可以,省掉多次的,內(nèi)存申請(qǐng),和數(shù)據(jù)搬移操作
3,容器無(wú)法存儲(chǔ)基本類型,比如 int long 需要轉(zhuǎn)換成包裝類型,類型的轉(zhuǎn)換有性能消耗。
4,業(yè)務(wù)開(kāi)發(fā),使用容器足夠,追求性能,首先用數(shù)組。
為什么數(shù)組要從 0 開(kāi)始編號(hào),而不是1?
從偏移角度理解a[0] 0為偏移量,如果從1計(jì)數(shù),會(huì)多出K-1。增加cpu負(fù)擔(dān)。為什么循環(huán)要寫(xiě)成 for(inti=0;i<3;i++)而不是 for(inti=0;i<=2;i++)。第一個(gè)直接就可以算出3-0 = 3 有三個(gè)數(shù)據(jù),而后者 2-0+1個(gè)數(shù)據(jù),多出1個(gè)加法運(yùn)算,很惱火。
參考:《數(shù)據(jù)結(jié)構(gòu)與算法之美》
總結(jié)
以上是生活随笔為你收集整理的扩容是元素还是数组_数组是如何随机访问元素?数组下标为什么从0开始,而不是1?...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 1载波把32个信道按_OFDM技术:相比
- 下一篇: 语言的顺序表的合拼_2020语文中考专题