摘要:內(nèi)存空間又被分為兩種,棧內(nèi)存與堆內(nèi)存。今天就堆棧隊(duì)列的內(nèi)容就大概說(shuō)到這里下一篇博客在繼續(xù)說(shuō)一下,有什么說(shuō)的不對(duì)或者不足的地方,請(qǐng)大家批評(píng)指正
棧的定義
棧是計(jì)算機(jī)科學(xué)中的一種抽象數(shù)據(jù)類(lèi)型,只允許在有序的線性數(shù)據(jù)集合的一端(稱(chēng)為堆棧頂端,英語(yǔ):top)進(jìn)行加入數(shù)據(jù)(英語(yǔ):push)和移除數(shù)據(jù)(英語(yǔ):pop)的運(yùn)算。因而按照后進(jìn)先出(LIFO, Last In First Out)的原理運(yùn)作。(百科全書(shū))
棧的常用操作棧中有兩個(gè)基本的操作
推入 :從棧的頂端推入一個(gè)數(shù)據(jù),依次往下推
彈出 :講棧頂端的數(shù)據(jù)移除
棧的基本提點(diǎn)就是
先進(jìn)后出,后進(jìn)先出
除了頭尾的節(jié)點(diǎn),每個(gè)元素都有一個(gè)先驅(qū)和一個(gè)后繼
對(duì)于棧的畫(huà)面的理解,可以想象成一個(gè)步槍彈夾添加子彈和射擊的過(guò)程
彈夾只有一個(gè)出入口進(jìn)行推入和彈出
效果圖如下
棧被創(chuàng)建的時(shí)機(jī)上邊說(shuō)了棧的基本結(jié)構(gòu)和方法,那么棧被創(chuàng)建的時(shí)候又做了什么事情呢
首先在我們的js在解釋執(zhí)行代碼的時(shí)候,最先遇到的就是全局代碼,所以在一開(kāi)始的時(shí)候首先就會(huì)向棧里邊壓入一個(gè)全局執(zhí)行上下文
全局上下文 只有在全局執(zhí)行環(huán)境被銷(xiāo)毀的時(shí)候才會(huì)被彈出銷(xiāo)毀
全局執(zhí)行上下文 只有一個(gè) 就是瀏覽器中的window對(duì)象,this默認(rèn)指向這個(gè)全局對(duì)象
然后當(dāng)執(zhí)行一個(gè)函數(shù)的時(shí)候,會(huì)在開(kāi)始先創(chuàng)建一個(gè)執(zhí)行上下文壓入棧中,如果里邊又執(zhí)行其他的函數(shù)的時(shí)候,又會(huì)創(chuàng)建一個(gè)新的執(zhí)行上下文壓入執(zhí)行棧中,直到函數(shù)執(zhí)行完畢,就會(huì)把函數(shù)的上下文從執(zhí)行棧中彈出
function fun3() { console.log("3") } function fun2() { fun3(); } function fun1() { fun2(); } fun1();
比如說(shuō)上邊這段代碼 ,他的進(jìn)棧出棧順序就是一開(kāi)始我們放的那兩張圖的效果
function fun1() { console.log("1") } function fun2() { console.log("2") } function fun3() { console.log("3") }
如果是這種的話 則會(huì)是最下邊有一個(gè)全局的棧,然后三個(gè)函數(shù)分別進(jìn)棧出棧
棧中的執(zhí)行上下文剛才我們?cè)谏线吿岬搅藞?zhí)行上下文的概念,執(zhí)行上下文是跟函數(shù)相關(guān)的,執(zhí)行上下文分為兩個(gè)階段
創(chuàng)建階段
執(zhí)行階段
首先創(chuàng)建階段
掃描變量和函數(shù)(確定變量環(huán)境)
確定this指向
確定詞法環(huán)境
簡(jiǎn)單說(shuō)一下詞法環(huán)境和變量環(huán)境的區(qū)別,我個(gè)人理解的就是說(shuō)詞法環(huán)境是包含變量環(huán)境的
在js里邊原型鏈大家都不陌生 ,js在當(dāng)前的對(duì)象里邊找不到所使用的屬性的話會(huì)去他的上一級(jí)去找
直到Object,再找不到就會(huì)undefined ,這里邊 當(dāng)前對(duì)象的作用域就是他的變量環(huán)境,而詞法環(huán)境則是與之關(guān)聯(lián)的的執(zhí)行上下文中聲明的變量
在創(chuàng)建階段 函數(shù)的聲明會(huì)被儲(chǔ)存在當(dāng)前的變量環(huán)境之中,var的變量的話則會(huì)被設(shè)置成undefined
,所以我們?cè)诼暶髦熬涂梢栽L問(wèn)到var聲明的變量 ,but他是一個(gè)undfined
然后就是執(zhí)行階段了
這個(gè)時(shí)候已經(jīng)完成了對(duì)所有變量的分配,開(kāi)始執(zhí)行代碼
隊(duì)列的定義隊(duì)列是一種比較高效的數(shù)據(jù)結(jié)構(gòu),他與棧不同的是,隊(duì)列只能在隊(duì)尾插入元素,在隊(duì)首刪除元素,
隊(duì)列用生活中的事物距離的話,大家可以想想一下沙漏,先進(jìn)入的沙子先出去,后進(jìn)去的沙子后出去
隊(duì)列比棧高效的地方就在于,循環(huán)的時(shí)候,棧會(huì)開(kāi)辟一個(gè)新的臨時(shí)棧,然后進(jìn)行排序,再循環(huán),最后在確保不打亂原有順序的情況下 排列回去
隊(duì)列則不需要這么多步驟
js模擬隊(duì)列實(shí)現(xiàn)隊(duì)列常用的一些操作有
向隊(duì)尾添加一個(gè)元素
刪除隊(duì)首元素
顯示所有元素
清空隊(duì)列
隊(duì)列是否為空
就先拿這些常用的方法實(shí)現(xiàn)以下,老規(guī)矩,請(qǐng)大家看代碼
// 隊(duì)列類(lèi) class Queue { constructor() { this.dataStore = [] } //新增 addQueue(val) { this.dataStore.push(val); } //刪除隊(duì)列首的元素 delQueue() { return this.queueIsNone()?console.log("隊(duì)列空了"):this.dataStore.shift() } //隊(duì)列是否為空 queueIsNone() { return this.dataStore.length == 0 } //查看所有元素 showQueue() { return this.dataStore.join(" "); } //清空隊(duì)列 clearQueue() { this.dataStor = []; this.showQueue() console.log("隊(duì)列空了") } } // 隊(duì)列實(shí)例 let queueOne = new Queue() /** * @author: 周靖松 * @information: 進(jìn)隊(duì) * @Date: 2019-06-11 21:01:28 */ function QueueIn (){ queueOne.addQueue(funStackBox.value) console.log(queueOne.showQueue()) } /** * @author: 周靖松 * @information: 出隊(duì) * @Date: 2019-06-11 21:01:35 */ function QueueOut (){ queueOne.delQueue() console.log(queueOne.showQueue()) } /** * @author: 周靖松 * @information: 清空隊(duì)列 * @Date: 2019-06-11 21:05:35 */ function QueueClear(){ queueOne.clearQueue() }
上邊的代碼 大家可以自己寫(xiě)個(gè)html試一下哈,html就不寫(xiě)了直接貼一下效果圖
另外雖然剛才我們?cè)倮又惺怯脭?shù)據(jù)去模擬的棧和隊(duì)列的實(shí)現(xiàn),but 數(shù)組他其實(shí)并不是一個(gè)棧內(nèi)存,他是一個(gè)堆內(nèi)存
堆的定義若是滿(mǎn)足以下特性,即可稱(chēng)為堆:是計(jì)算機(jī)科學(xué)中的一種特別的樹(shù)狀數(shù)據(jù)結(jié)構(gòu)??梢越o堆中的任意節(jié)點(diǎn)添加新的節(jié)點(diǎn)(百科全書(shū))
堆和棧的區(qū)別在JS中,每一個(gè)數(shù)據(jù)都需要一個(gè)內(nèi)存空間。內(nèi)存空間又被分為兩種,棧內(nèi)存(stack)與堆內(nèi)存(heap)。
棧為自動(dòng)分配的內(nèi)存空間,它由系統(tǒng)自動(dòng)釋放
堆是動(dòng)態(tài)分配的內(nèi)存,大小不定也不會(huì)自動(dòng)釋放
也不是說(shuō)不會(huì)自動(dòng)釋放,堆在沒(méi)有引用的時(shí)候,下一次垃圾回收機(jī)制出現(xiàn)的時(shí)候會(huì)回收他的內(nèi)存
js 的變量分為基本類(lèi)型和引用類(lèi)型
基本類(lèi)型 (Undefined、Null、Boolean、Number和String)
基本類(lèi)型在內(nèi)存中占據(jù)空間小、大小固定 ,他們的值保存在棧(stack)空間,是按值來(lái)訪問(wèn)
引用類(lèi)型 (對(duì)象、數(shù)組、函數(shù))
引用類(lèi)型占據(jù)空間大、大小不固定, 棧內(nèi)存中存放地址指向堆(heap)內(nèi)存中的對(duì)象。是按引用訪問(wèn)的
盜個(gè)圖舉個(gè)例子
js不允許直接訪問(wèn)堆內(nèi)存中的位置,因此我們不能直接操作對(duì)象的堆內(nèi)存空間,所以棧中存的是一個(gè)指向堆內(nèi)存的一個(gè)地址
當(dāng)我們要訪問(wèn)堆內(nèi)存中的引用數(shù)據(jù)類(lèi)型時(shí),實(shí)際上我們首先是從棧中獲取了該對(duì)象的地址引用(或者地址指針),然后再?gòu)亩褍?nèi)存中取得我們需要的數(shù)據(jù)。
今天就堆棧隊(duì)列的內(nèi)容就大概說(shuō)到這里 下一篇博客 在繼續(xù)說(shuō)一下, 有什么說(shuō)的不對(duì)或者不足的地方,請(qǐng)大家批評(píng)指正
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/105532.html
摘要:棧和隊(duì)列是開(kāi)發(fā)中最常用的兩種數(shù)據(jù)結(jié)構(gòu)。如果又有數(shù)據(jù)入棧,的值將增加到。如果一個(gè)數(shù)據(jù)從棧中被取出,的值將會(huì)減少為。隊(duì)列與棧類(lèi)似,隊(duì)列也是一個(gè)線性數(shù)據(jù)結(jié)構(gòu)。與棧不同的是,隊(duì)列只刪除最先添加的數(shù)據(jù)?,F(xiàn)在,讓我們將棧大小的實(shí)現(xiàn)應(yīng)用到隊(duì)列中。 翻譯:瘋狂的技術(shù)宅英文:https://code.tutsplus.com/art...說(shuō)明:本文翻譯自系列文章《Data Structures With...
摘要:于是翻出了機(jī)房里的這本學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法開(kāi)始學(xué)習(xí)程序員的基礎(chǔ)知識(shí)。這本書(shū)用了我最熟悉的來(lái)實(shí)現(xiàn)各種數(shù)據(jù)結(jié)構(gòu)和算法,而且書(shū)很薄,可以說(shuō)是一本不錯(cuò)的入門(mén)教程。隊(duì)列在頭部刪除元素,尾部添加元素。 本系列所有文章:第一篇文章:學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法之棧與隊(duì)列第二篇文章:學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法之鏈表第三篇文章:學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法之集合第四篇文章:學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法之字典和散列表第五篇文章:學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算...
摘要:對(duì)于棧和堆的理解棧棧是有結(jié)構(gòu)的,存儲(chǔ)的時(shí)候按順序存儲(chǔ),先存進(jìn)去的在棧的最下面,遵循先進(jìn)后出的原則,棧中存放的是基本數(shù)據(jù)類(lèi)型變量的值,以及引用數(shù)據(jù)類(lèi)型中指向堆的引用地址,占據(jù)的空間大小一般是確定的。 對(duì)于棧和堆的理解 棧(stack) 棧是有結(jié)構(gòu)的,存儲(chǔ)的時(shí)候按順序存儲(chǔ),先存進(jìn)去的在棧的最下面,遵循’先進(jìn)后出‘的原則,棧中存放的是基本數(shù)據(jù)類(lèi)型變量的值,以及引用數(shù)據(jù)類(lèi)型中指向堆的引用(地址...
摘要:之?dāng)?shù)組操作接下來(lái)就是數(shù)據(jù)結(jié)構(gòu)的第一部分,棧。以字符串顯示棧中所有內(nèi)容方法的實(shí)現(xiàn)說(shuō)明需要往棧中添加新元素,元素位置在隊(duì)列的末尾。的前端樂(lè)園原文鏈接寒假前端學(xué)習(xí)學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法,棧與隊(duì)列 本系列的第一篇文章: 學(xué)習(xí)JavaScript數(shù)據(jù)結(jié)構(gòu)與算法(一),棧與隊(duì)列第二篇文章:學(xué)習(xí)JavaScript數(shù)據(jù)結(jié)構(gòu)與算法(二):鏈表第三篇文章:學(xué)習(xí)JavaScript數(shù)據(jù)結(jié)構(gòu)與算法(三):集合第...
摘要:事件循環(huán)背景是一門(mén)單線程非阻塞的腳本語(yǔ)言,單線程意味著,代碼在執(zhí)行的任何時(shí)候,都只有一個(gè)主線程來(lái)處理所有的任務(wù)。在意識(shí)到該問(wèn)題之際,新特性中的可以讓成為一門(mén)多線程語(yǔ)言,但實(shí)際開(kāi)發(fā)中使用存在著諸多限制。這個(gè)地方被稱(chēng)為執(zhí)行棧。 事件循環(huán)(Event Loop) 背景 JavaScript是一門(mén)單線程非阻塞的腳本語(yǔ)言,單線程意味著,JavaScript代碼在執(zhí)行的任何時(shí)候,都只有一個(gè)主線程來(lái)...
閱讀 1172·2023-04-26 01:35
閱讀 2566·2021-11-02 14:44
閱讀 7709·2021-09-22 15:38
閱讀 2248·2021-09-06 15:11
閱讀 3740·2019-08-30 15:53
閱讀 843·2019-08-29 16:54
閱讀 670·2019-08-26 13:48
閱讀 1787·2019-08-26 13:47