前端算法與數(shù)據(jù)結(jié)構(gòu)——數(shù)組/棧/隊(duì)列

數(shù)組

作為最簡(jiǎn)單诗宣,最基礎(chǔ)的一個(gè)數(shù)據(jù)結(jié)構(gòu),大多數(shù)語(yǔ)言都天然地對(duì)數(shù)組有著原生的表達(dá)想诅,Javascript亦然召庞。

“開(kāi)箱即用”,而不必自行實(shí)現(xiàn)来破,非常方便篮灼。

首先我們需要知道: JS 數(shù)組未必是真正的數(shù)組

在大多數(shù)的計(jì)算機(jī)語(yǔ)言中,數(shù)組都對(duì)應(yīng)著一段連續(xù)的內(nèi)存徘禁。如果我們想要在任意位置刪除一個(gè)元素诅诱,那么該位置往后的所有元素,都需要往前挪一個(gè)位置晌坤;相應(yīng)地逢艘,如果要在任意位置新增一個(gè)元素旦袋,那么該位置往后的所有元素也都要往后挪一個(gè)位置。

我們假設(shè)數(shù)組的長(zhǎng)度是 n它改,那么因增加/刪除操作導(dǎo)致需要移動(dòng)的元素?cái)?shù)量疤孕,就會(huì)隨著數(shù)組長(zhǎng)度 n 的增大而增大,呈一個(gè)線性關(guān)系央拖。所以說(shuō)數(shù)組增加/刪除操作對(duì)應(yīng)的復(fù)雜度就是 O(n)祭阀。

但 JS 中不一定是。

JS比較特別鲜戒。如果我們?cè)谝粋€(gè)數(shù)組中只定義了一種類(lèi)型的元素专控,比如:

const arr = [1,2,3,4]

它是一個(gè)純數(shù)字?jǐn)?shù)組,那么對(duì)應(yīng)的確實(shí)是連續(xù)內(nèi)存遏餐。

但如果我們定義了不同類(lèi)型的元素:

const arr = ['haha', 1, {a:1}]

它對(duì)應(yīng)的就是一段非連續(xù)的內(nèi)存伦腐。此時(shí),JS 數(shù)組不再具有數(shù)組的特征失都,其底層使用哈希映射分配內(nèi)存空間柏蘑,是由對(duì)象鏈表來(lái)實(shí)現(xiàn)的。

所以說(shuō)“JS 數(shù)組未必是真正的數(shù)組”粹庞。

在各大教材(包括百科詞條)對(duì)數(shù)組的定義中咳焚,都有一個(gè)“存儲(chǔ)在連續(xù)的內(nèi)存空間里”這樣的必要條件。

這同時(shí)是前端面試題中庞溜,數(shù)組和鏈表辨析的答案革半,我們要意識(shí)到?JS 數(shù)組和常規(guī)數(shù)組的不同,相對(duì)于數(shù)組來(lái)說(shuō)流码,鏈表有個(gè)明顯的有點(diǎn)又官,就是添加和刪除元素都不需要挪動(dòng)多余的元素。

Tips:要對(duì)數(shù)組格外走心漫试,畢竟后面需要它幫忙的地方會(huì)非常多赏胚。

數(shù)組的創(chuàng)建:

最多的創(chuàng)建方式:

const arr = [ 1, 2, 3 ]

但是在算法題中,很多時(shí)候我們初始化一個(gè)數(shù)組時(shí)商虐,并不知道它內(nèi)部元素的情況觉阅,這種場(chǎng)景下,推薦大家使用new的方式初始化數(shù)組

const arr = new Array()

// 等價(jià)于

const arr = []

不過(guò)我們使用構(gòu)造函數(shù)秘车,可不是為了創(chuàng)建空數(shù)組這么無(wú)聊典勇。

我們需要它的時(shí)候,往往是因?yàn)槲覀冇?i>創(chuàng)造指定長(zhǎng)度的空數(shù)組這樣的需求叮趴。需要多長(zhǎng)的數(shù)組就給它傳多大的參數(shù)割笙。

const arr = new Array(7)

// 創(chuàng)建一個(gè)指定長(zhǎng)度為7的數(shù)組

在一些場(chǎng)景還需要我們創(chuàng)建一個(gè)指定長(zhǎng)度,同時(shí)每一個(gè)元素的值也都確定的數(shù)組這時(shí)我們可以調(diào)用fill方法伤溉,假設(shè)需求是每一個(gè)坑里都填上一個(gè)1般码,只需給它fill一個(gè)1:

const arr = (new Array(7)).fill(1)

// [1,1,1,1,1,1,1]

數(shù)組的訪問(wèn)和遍歷:

訪問(wèn)數(shù)組中的元素,我們直接在中括號(hào)中指定其索引即可:

arr[0]? ? // 訪問(wèn)索引下標(biāo)為0的元素

而遍歷數(shù)組乱顾,這個(gè)方法就多了板祝,不過(guò)目的往往都是一致的(訪問(wèn)數(shù)組中的每一個(gè)元素,并且知道當(dāng)前元素的索引)走净。這里我們介紹三個(gè)方法:

1.for循環(huán)

這是最基礎(chǔ)的操作券时。我們可以通過(guò)循環(huán)數(shù)組的下標(biāo),來(lái)依次訪問(wèn)每個(gè)值:

// 獲取數(shù)組的長(zhǎng)度

const len = arr.length

for(let i=0;i<len;i++) {

????// 輸出數(shù)組的元素值伏伯,輸出當(dāng)前索引 console.log(arr[i], i)

}

2.forEach方法

通過(guò)區(qū)forEach方法中傳入函數(shù)的第一個(gè)入?yún)⒑偷诙€(gè)入?yún)㈤俣矗覀円部梢匀〉綌?shù)組每個(gè)元素的值及其對(duì)應(yīng)索引:

arr.forEach((item, index)=> {

????// 輸出數(shù)組的元素值,輸出當(dāng)前索引

????console.log(item, index)

})

3.map方法

map方法在調(diào)用形式上與forEach無(wú)異说搅,區(qū)別于map方法會(huì)根據(jù)你傳入的函數(shù)邏輯對(duì)數(shù)組的每一個(gè)元素進(jìn)行處理炸枣,進(jìn)而返回一個(gè)全新的數(shù)組。

所以其實(shí)map做的事情不僅僅是遍歷弄唧,而是在遍歷的基礎(chǔ)上再加工抛虏。當(dāng)我們需要對(duì)數(shù)組內(nèi)容做批量修改,同時(shí)修改邏輯又高度一致時(shí)套才,就可以調(diào)用map來(lái)達(dá)到我們的目的:

const newArr = arr.map((item, index)=> {

????// 輸出數(shù)組的元素值,輸出當(dāng)前索引

????console.log(item, index)

????// 在當(dāng)前元素值的基礎(chǔ)上加1

????return item+1

})

小建議:沒(méi)有特殊的需求慕淡,統(tǒng)一使用for循環(huán)來(lái)實(shí)現(xiàn)遍歷背伴。因?yàn)?b>從性能上看,for循環(huán)遍歷起來(lái)是最快的峰髓。

二維數(shù)組


一維數(shù)組


二維數(shù)組

二維數(shù)組的特點(diǎn):從形狀上看傻寂,相對(duì)于一維數(shù)組一條“線”一般的布局,二維數(shù)組更像是一個(gè)“面”携兵。拿咱們這個(gè)例子來(lái)說(shuō)疾掰,這里的二維數(shù)組邏輯分布圖就宛如一個(gè)正方形。當(dāng)然啦徐紧,如果我們稍微延長(zhǎng)一下其中的一邊静檬,它也可以是一個(gè)矩形。

在數(shù)學(xué)中并级,形如這樣長(zhǎng)方陣列排列的復(fù)數(shù)或?qū)崝?shù)集合拂檩,被稱(chēng)為“矩陣”。因此二維數(shù)組的別名就叫“矩陣”嘲碧。

必須要記住“矩陣”和“二維數(shù)組”之間的等價(jià)關(guān)系稻励。在算法題目中,見(jiàn)到“矩陣”時(shí)愈涩,能夠立刻反射出它說(shuō)的是二維數(shù)組,不被別名整懵逼,這就夠了习劫。

二維數(shù)組的初始化:

const arr =(new Array(7)).fill([])

以上的方式對(duì)嗎萤彩?乍一看,沒(méi)什么毛病亦镶。

但是當(dāng)你想修改某一個(gè)坑里的數(shù)組的值的時(shí)候,你就會(huì)發(fā)現(xiàn)問(wèn)題。

正確的初始化一個(gè)二維數(shù)組的方式:

const len = arr.length

for(let i=0;i<len;i++) {

????// 將數(shù)組的每一個(gè)坑位初始化為數(shù)組 arr[i] = []

}

二維數(shù)組的訪問(wèn):

訪問(wèn)二維數(shù)組和訪問(wèn)一維數(shù)組差別不大趣惠,區(qū)別在于我們現(xiàn)在需要的是兩層循環(huán)。

一維數(shù)組用 for 循環(huán)遍歷只需一層循環(huán)身害,二維數(shù)組是兩層味悄,三維數(shù)組就是三層。依次類(lèi)推塌鸯,N 維數(shù)組需要 N 層循環(huán)來(lái)完成遍歷侍瑟。

這遠(yuǎn)不是數(shù)組的全部,目前僅圍繞數(shù)組最基本的操作進(jìn)行介紹丙猬,在javascript數(shù)據(jù)結(jié)構(gòu)中涨颜,數(shù)組幾乎是基石一般的存在。


棧和隊(duì)列

在javascript中茧球,隊(duì)列的實(shí)現(xiàn)一般都要依賴于數(shù)組庭瑰,“特別的數(shù)組”。

(注:實(shí)際上抢埋,棧和隊(duì)列作為兩種運(yùn)算受限的線性表弹灭,用鏈表來(lái)實(shí)現(xiàn)也是沒(méi)問(wèn)題的。只是從前端面試做題的角度來(lái)說(shuō)揪垄,基于鏈表來(lái)實(shí)現(xiàn)棧和隊(duì)列約等于脫褲子放屁(鏈表實(shí)現(xiàn)起來(lái)會(huì)比數(shù)組麻煩得多穷吮,做不到開(kāi)箱即用),基本沒(méi)人會(huì)這么干饥努。這里大家按照數(shù)組的思路往下走就行了)

作為有經(jīng)驗(yàn)的前端捡鱼,大家對(duì)javascript數(shù)組的操作恐怕都不陌生。

但我們今天講的棧和隊(duì)列酷愧,兩者的區(qū)別在于驾诈,它們各自對(duì)數(shù)組的增刪操作有著不一樣的限制。因此我們先熟悉一下javascript數(shù)組中的增刪操作具有什么樣的特性溶浴,對(duì)應(yīng)的方法有哪些翘鸭?

增加:

unshift 方法-添加元素到數(shù)組的頭部

push 方法-添加元素到數(shù)組的尾部

splice 方法-添加元素到數(shù)組的任何位置

刪除:

shift 方法-刪除數(shù)組頭部的元素

pop 方法-刪除數(shù)組尾部的元素

splice 方法-刪除數(shù)組任意位置的元素

棧(Stack)——只用 pop 和 push 完成增刪的“數(shù)組”

棧是一種后進(jìn)先出(LIFO,Last In First Out)的數(shù)據(jù)結(jié)構(gòu)戳葵。

隊(duì)列(Queue)——只用 push 和 shift 完成增刪的“數(shù)組”

隊(duì)列是一種先進(jìn)先出(FIFO就乓,F(xiàn)irst In First Out)的數(shù)據(jù)結(jié)構(gòu)。

閱讀掘金小冊(cè)的《前端算法與數(shù)據(jù)結(jié)構(gòu)面試:底層邏輯解讀與大廠真題訓(xùn)練》所獲。富有的朋友們值得購(gòu)買(mǎi)一讀生蚁。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末噩翠,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子邦投,更是在濱河造成了極大的恐慌伤锚,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,000評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件志衣,死亡現(xiàn)場(chǎng)離奇詭異屯援,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)念脯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)狞洋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人绿店,你說(shuō)我怎么就攤上這事吉懊。” “怎么了假勿?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,561評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵借嗽,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我转培,道長(zhǎng)恶导,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,782評(píng)論 1 298
  • 正文 為了忘掉前任浸须,我火速辦了婚禮惨寿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘羽戒。我一直安慰自己,他們只是感情好虎韵,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布易稠。 她就那樣靜靜地躺著,像睡著了一般包蓝。 火紅的嫁衣襯著肌膚如雪驶社。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,394評(píng)論 1 310
  • 那天测萎,我揣著相機(jī)與錄音亡电,去河邊找鬼。 笑死硅瞧,一個(gè)胖子當(dāng)著我的面吹牛份乒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,952評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼或辖,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼瘾英!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起颂暇,我...
    開(kāi)封第一講書(shū)人閱讀 39,852評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤缺谴,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后耳鸯,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體湿蛔,經(jīng)...
    沈念sama閱讀 46,409評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評(píng)論 3 341
  • 正文 我和宋清朗相戀三年县爬,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了阳啥。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,615評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡捌省,死狀恐怖苫纤,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情纲缓,我是刑警寧澤卷拘,帶...
    沈念sama閱讀 36,303評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站祝高,受9級(jí)特大地震影響栗弟,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜工闺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評(píng)論 3 334
  • 文/蒙蒙 一乍赫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧陆蟆,春花似錦雷厂、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,470評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至林束,卻和暖如春像棘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背壶冒。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,571評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工缕题, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人胖腾。 一個(gè)月前我還...
    沈念sama閱讀 49,041評(píng)論 3 377
  • 正文 我出身青樓烟零,卻偏偏與公主長(zhǎng)得像瘪松,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子瓶摆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容