真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

程序猿修仙之路--數(shù)據(jù)結(jié)構(gòu)之你是否真的懂?dāng)?shù)組?

但凡IT江湖俠士,算法與數(shù)據(jù)結(jié)構(gòu)為必修之課。早有前輩已經(jīng)明確指出:程序=算法+數(shù)據(jù)結(jié)構(gòu) 。要想在之后的江湖歷練中通關(guān),數(shù)據(jù)結(jié)構(gòu)必不可少。數(shù)據(jù)結(jié)構(gòu)與算法相輔相成,亦是陰陽(yáng)互補(bǔ)之法。

成都創(chuàng)新互聯(lián)主要從事網(wǎng)站制作、網(wǎng)站設(shè)計(jì)、網(wǎng)頁(yè)設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)大興安嶺,10余年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來(lái)電咨詢建站服務(wù):028-86922220

開(kāi)篇

說(shuō)道數(shù)組,幾乎每個(gè)IT江湖人士都不陌生,甚至過(guò)半人還會(huì)很自信覺(jué)的它很簡(jiǎn)單。
的確,在菜菜所知道的編程語(yǔ)言中幾乎都會(huì)有數(shù)組的影子。不過(guò)它不僅僅是一種基礎(chǔ)的數(shù)據(jù)類型,更是一種基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu)。如果你覺(jué)的對(duì)數(shù)組足夠了解,那能不能回答一下:

  • 數(shù)組的本質(zhì)定義?
  • 數(shù)組的內(nèi)存結(jié)構(gòu)?
  • 數(shù)組有什么優(yōu)勢(shì)?
  • 數(shù)組有什么劣勢(shì)?
  • 數(shù)組的應(yīng)用場(chǎng)景?
  • 數(shù)組為什么大部分都從0開(kāi)始編號(hào)?
  • 數(shù)組能否用其他容器來(lái)代替,例如c#中的List?

定義

百科

所謂數(shù)組,是相同的元素序列。數(shù)組是在程序設(shè)計(jì)中,為了處理方便,把具有相同類型的若干元素按無(wú)序的形式組織起來(lái)的一種形式。

正如以上所述,數(shù)組在應(yīng)用上屬于數(shù)據(jù)的容器。不過(guò)我還是要補(bǔ)充兩點(diǎn):

  1. 數(shù)組在數(shù)據(jù)結(jié)構(gòu)范疇屬于一種線性結(jié)構(gòu),也就是只有前置節(jié)點(diǎn)和后續(xù)節(jié)點(diǎn)的數(shù)據(jù)結(jié)構(gòu),除數(shù)組之外,像我們平時(shí)所用的隊(duì)列,棧,鏈表等也都屬于線性結(jié)構(gòu)。
    程序猿修仙之路--數(shù)據(jù)結(jié)構(gòu)之你是否真的懂?dāng)?shù)組?

有線性結(jié)構(gòu)當(dāng)然就有非線性結(jié)構(gòu),比如之后我們要介紹的二叉樹(shù),圖 等等,這里不再展開(kāi)~~~
程序猿修仙之路--數(shù)據(jù)結(jié)構(gòu)之你是否真的懂?dāng)?shù)組?

  1. 數(shù)組元素在內(nèi)存分配上是連續(xù)的。這一點(diǎn)對(duì)于數(shù)組這種數(shù)據(jù)結(jié)構(gòu)來(lái)說(shuō)非常重要,甚至可以說(shuō)是它最大的“殺手锏”。下邊會(huì)有更詳細(xì)的介紹。

優(yōu)勢(shì)和劣勢(shì)

優(yōu)勢(shì)

我相信所有人在使用數(shù)組的時(shí)候都知道數(shù)組可以按照下標(biāo)來(lái)訪問(wèn),例如 array[1] 。作為一種最基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu)是什么使數(shù)組具有這樣的隨機(jī)訪問(wèn)方式呢?天性聰慧的你可能已經(jīng)想到了:內(nèi)存連續(xù)+相同數(shù)據(jù)類型。
現(xiàn)在我們抽象一下數(shù)據(jù)在內(nèi)存上分配的情景。

程序猿修仙之路--數(shù)據(jù)結(jié)構(gòu)之你是否真的懂?dāng)?shù)組?

  • 說(shuō)到數(shù)組按下標(biāo)訪問(wèn),不得不說(shuō)一下大多數(shù)人的一個(gè)“誤解”:數(shù)組適合查找元素。為什么說(shuō)是誤解呢,是因?yàn)檫@種說(shuō)法不夠準(zhǔn)確,準(zhǔn)確的說(shuō)數(shù)組適合按下標(biāo)來(lái)查找元素,而且按照下標(biāo)查找元素的時(shí)間復(fù)雜度是O(1)。為什么呢?我們知道要訪問(wèn)數(shù)組的元素需要知道元素在內(nèi)存中對(duì)應(yīng)的內(nèi)存地址,而數(shù)組指向的內(nèi)存的地址為首元素的地址,即:array[0]。由于數(shù)組的每個(gè)元素都是相同的類型,每個(gè)類型占用的字節(jié)數(shù)系統(tǒng)是知道的,所以要想訪問(wèn)一個(gè)數(shù)組的元素,按照下標(biāo)查找可以抽象為:

    array[n]=array[0]+size*n

以上是元素地址的運(yùn)算,其中size為每個(gè)元素的大小,如果為int類型數(shù)據(jù),那size就為4個(gè)字節(jié)。其實(shí)確切的說(shuō),n的本質(zhì)是一個(gè)離首元素的偏移量,所以array[n]就是距離首元素n個(gè)偏移量的元素,因此計(jì)算array[n]的內(nèi)存地址只需以上公式。
程序猿修仙之路--數(shù)據(jù)結(jié)構(gòu)之你是否真的懂?dāng)?shù)組?

論證一下,如果下標(biāo)從1開(kāi)始計(jì)算,那array[n]的內(nèi)存地址計(jì)算公式就會(huì)變?yōu)椋?/p>

array[n]=array[0]+size*(n-1)

對(duì)比很容易發(fā)現(xiàn),從1開(kāi)始編號(hào)比從0開(kāi)始編號(hào)每次獲取內(nèi)存地址都多了一次 減法運(yùn)算,也就多了一次cpu指令的運(yùn)行。這也是數(shù)組從0下標(biāo)開(kāi)始訪問(wèn)一個(gè)原因。

其實(shí)還有一種可能性,那就是所有現(xiàn)代編程語(yǔ)言的鼻祖:C語(yǔ)言,它是從0開(kāi)始計(jì)數(shù)下標(biāo)的,所以現(xiàn)在所有衍生出來(lái)的后代語(yǔ)言也就延續(xù)了這個(gè)傳統(tǒng)。雖然不符合人類的思想,但是符合計(jì)算機(jī)的原理。當(dāng)然也有一些語(yǔ)言可以設(shè)置為不從下標(biāo)0開(kāi)始計(jì)算,這里不再展開(kāi),有興趣的可以去搜索一下。

  • 由于數(shù)組的連續(xù)性,所以在遍歷數(shù)組的時(shí)候非???,不僅得益于數(shù)組的連續(xù)性,另外也得益于cpu的緩存,因?yàn)閏pu讀取緩存只能讀取連續(xù)內(nèi)存的內(nèi)容,所以數(shù)組的連續(xù)性正好符合cpu緩存的指令原理,要知道cpu緩存的速度要比內(nèi)存的速度快上很多。
劣勢(shì)
  1. 由于數(shù)組在內(nèi)存排列上是連續(xù)的,而且要保持這種連續(xù)性,所以當(dāng)增加一個(gè)元素或刪除一個(gè)元素的時(shí)候,為了保證連續(xù)性,需要做大量元素的移動(dòng)工作。
    舉個(gè)栗子:要在數(shù)組頭部插入一個(gè)新元素,為了在頭部騰出位置,所有的元素都要后移一位,假設(shè)元素個(gè)數(shù)為n,這就導(dǎo)致了時(shí)間復(fù)雜度為O(n)的一次操作,當(dāng)然如果是在數(shù)組末尾插入新元素,其他所有元素都不必移動(dòng),操作的時(shí)間復(fù)雜度為O(1)。

當(dāng)然這里有一個(gè)技巧:如果你的業(yè)務(wù)要求并不是數(shù)組連續(xù)有序的,當(dāng)在位置k插入元素的時(shí)候,只需要把k元素轉(zhuǎn)移到數(shù)組末尾,新元素插入到k位置即可。當(dāng)然仔細(xì)沉思一下這種業(yè)務(wù)場(chǎng)景可能性太小了,數(shù)組都可以無(wú)序,我直接插入末尾即可,沒(méi)有必要非得在k位置插入把。~~

當(dāng)然還有一個(gè)特殊場(chǎng)景:如果是多次連續(xù)的k位置插入操作,我們完全可以合并為一次“批量插入”操作:把k之后的元素整體移動(dòng)sum(插入次數(shù))個(gè)位置,無(wú)需一個(gè)個(gè)位置移動(dòng),把三次操作的時(shí)間復(fù)雜度合并為一次。

與插入對(duì)應(yīng)的就有刪除操作,同理,刪除操作數(shù)組為了保持連續(xù)性,也需要元素的移動(dòng)。

綜上所述,數(shù)組在添加和刪除元素的場(chǎng)景下劣勢(shì)比較明顯,所以在具體業(yè)務(wù)場(chǎng)景下應(yīng)該避免頻繁添加和刪除的操作。

  1. 數(shù)組的連續(xù)性就要求創(chuàng)建數(shù)組的時(shí)候,內(nèi)存必須有相應(yīng)大小的連續(xù)區(qū)塊,如果不存在,數(shù)組就有可能出現(xiàn)創(chuàng)建失敗的現(xiàn)象。在某些高級(jí)語(yǔ)言中(比如c#,golang,java)就有可能引發(fā)一次GC(垃圾回收)操作,GC操作在系統(tǒng)運(yùn)行中是非常昂貴的,有的語(yǔ)言甚至?xí)炱鹚芯€程的操作,對(duì)外的表現(xiàn)就是“暫停服務(wù)”。
  2. 數(shù)組要求所有元素為同一個(gè)類型。在存儲(chǔ)數(shù)據(jù)維度,它可能算是一種劣勢(shì),但是為了按照下標(biāo)快速查找元素,業(yè)務(wù)中這也是一種優(yōu)勢(shì)。仁者見(jiàn)仁智者見(jiàn)智而已。
  3. 數(shù)組是長(zhǎng)度固定的數(shù)據(jù)結(jié)構(gòu),所以在原始數(shù)組的基礎(chǔ)上擴(kuò)容是不可能的,有的語(yǔ)言可能實(shí)現(xiàn)數(shù)組的“偽擴(kuò)容”,為什么說(shuō)是“偽”呢,因?yàn)樵砥鋵?shí)是創(chuàng)建了一個(gè)容量更大的數(shù)組來(lái)存放原數(shù)組元素,發(fā)生了數(shù)據(jù)復(fù)制的過(guò)程,只不過(guò)對(duì)于調(diào)用者而已透明而已。
  4. 數(shù)組有訪問(wèn)越界的可能。我們按照下標(biāo)訪問(wèn)數(shù)組的時(shí)候如果下標(biāo)超出了數(shù)組長(zhǎng)度,在現(xiàn)代多數(shù)高級(jí)語(yǔ)言中,直接就會(huì)引發(fā)異常了,但是一些低級(jí)語(yǔ)言比如C 有可能會(huì)訪問(wèn)到數(shù)組元素以外的數(shù)據(jù),因?yàn)橐L問(wèn)的內(nèi)存地址確實(shí)存在。

其他

  1. 很多編程語(yǔ)言中你會(huì)發(fā)現(xiàn)“純數(shù)組”并沒(méi)有提供直接刪除元素的方法(例如:c#,golang),而是需要將數(shù)組轉(zhuǎn)化為另一種數(shù)據(jù)結(jié)構(gòu)來(lái)實(shí)現(xiàn)數(shù)組元素的刪除。比如在golang種可以轉(zhuǎn)化為slice。這也驗(yàn)證了數(shù)組的不變性。

應(yīng)用場(chǎng)景

我們學(xué)習(xí)的每個(gè)數(shù)據(jù)結(jié)構(gòu)其實(shí)都有對(duì)應(yīng)的適合場(chǎng)景,只不過(guò)是場(chǎng)景多少的問(wèn)題,具體什么時(shí)候用,需要我們對(duì)該數(shù)據(jù)結(jié)構(gòu)的特性做深入分析。
關(guān)于數(shù)組的特性,通過(guò)以上介紹可以知道最大的一個(gè)亮點(diǎn)就是按照下標(biāo)訪問(wèn),那有沒(méi)有具體業(yè)務(wù)映射這種特性呢?

  1. 相信很多IT人士都遇到過(guò)會(huì)員機(jī)制,每個(gè)會(huì)員到達(dá)一定的經(jīng)驗(yàn)值就會(huì)升級(jí),怎么判斷當(dāng)前的經(jīng)驗(yàn)是否到達(dá)升級(jí)條件呢?我們是不是可以這樣做:比如當(dāng)前會(huì)員等級(jí)為3,判斷是否到達(dá)等級(jí)4的經(jīng)驗(yàn)值,只需要array[4]的值判斷即可,大多數(shù)人把配置放到DB,資源耗費(fèi)太嚴(yán)重。也有的人放到其他容器緩存。但是大部分場(chǎng)景下查詢的時(shí)間復(fù)雜度要比數(shù)組大很多。
  2. 在分布式底層應(yīng)用中,我們會(huì)有利用一致性哈希方案來(lái)解決每個(gè)請(qǐng)求交給哪個(gè)服務(wù)器去處理的場(chǎng)景。有興趣的同學(xué)可以自己去研究一下。其中有一個(gè)環(huán)節(jié):根據(jù)哈希值查找對(duì)應(yīng)的服務(wù)器,這是典型的讀多寫少的應(yīng)用,而且比較偏底層。如果用其他數(shù)據(jù)結(jié)構(gòu)來(lái)解決大量的查找問(wèn)題,可能會(huì)觸碰到性能的瓶頸。而數(shù)據(jù)按下標(biāo)訪問(wèn)時(shí)間復(fù)雜度為O(1)的特性,使得數(shù)組在類似這些應(yīng)用中非常廣泛。

添加關(guān)注,查看更精美版本,收獲更多精彩

程序猿修仙之路--數(shù)據(jù)結(jié)構(gòu)之你是否真的懂?dāng)?shù)組?


本文標(biāo)題:程序猿修仙之路--數(shù)據(jù)結(jié)構(gòu)之你是否真的懂?dāng)?shù)組?
鏈接分享:http://weahome.cn/article/goccsc.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部