摘要:所以,可以這樣寫利用數(shù)組的方法,就可以實(shí)現(xiàn)在棧頂末尾添加新的元素了。因?yàn)闂5貎?nèi)部使用數(shù)組保存元素,所以數(shù)組地就是棧的長度。實(shí)現(xiàn)方法,方法用來清空棧中所有的元素。感興趣可以自行百度去了解原文鏈接行無忌的成長小屋如何用手動(dòng)實(shí)現(xiàn)一個(gè)棧
什么是棧(Stack)
棧是一種遵從后進(jìn)先出(LIFO)原則的有序集合。
新添加的或待刪除的元素都保存在棧的末尾,稱為棧頂,另一端叫棧底。
在棧里,新元素都靠近棧頂,舊元素都接近棧底
現(xiàn)實(shí)中的例子在生活中也能發(fā)現(xiàn)很多棧的例子。例如,廚房里堆放的盤子,總是疊在上方的先被使用;輸入框內(nèi)容進(jìn)行刪除時(shí),總是最后輸入的先刪除;彈夾中的子彈,越后裝入的,越先發(fā)射......
手動(dòng)實(shí)現(xiàn)一個(gè)棧首先,創(chuàng)建一個(gè)類來表示棧
function Stack () { }
我們需要選擇一種數(shù)據(jù)結(jié)構(gòu)來保存棧里的元素,可以選擇數(shù)組
function Stack(){ var items = []; //用來保存棧里的元素 }
接下來,為棧添加一些方法
push(element(s)); //添加新元素到棧頂 pop(); //移除棧頂?shù)脑兀瑫r(shí)返回被移除的元素 peek(); //返回棧頂?shù)脑兀粚?duì)棧做任何修改 isEmpty(); //如果棧里沒有任何元素就返回true,否則false clear(); //移除棧里的所有元素 size(); //返回棧里的元素個(gè)數(shù),類似于數(shù)組的length屬性
我們需要實(shí)現(xiàn)的第一個(gè)方法時(shí)push。用來往棧里添加新元素,有一點(diǎn)很重要:該方法只添加到棧頂,也就是棧的末尾。所以,可以這樣寫:
this.push = function (element) { items.push(element); }
利用數(shù)組的push方法,就可以實(shí)現(xiàn)在棧頂末尾添加新的元素了。
接著,來實(shí)現(xiàn)pop方法,用來實(shí)現(xiàn)移除棧里的元素。棧遵從LIFO(后進(jìn)先出)原則。移出去的是最后添加進(jìn)去的元素。因此,可以使用數(shù)組的pop方法。
this.pop = function () { return items.pop(); }
這樣一來,這個(gè)棧自然就遵從了LIFO原則
現(xiàn)在,再來為這個(gè)棧添額外的輔助方法。
如果想知道棧里最后添加的元素是什么,可以用peek方法。這個(gè)方法將返回棧頂?shù)脑?/p>
this.peek = function () { return items[items.length-1]; }
因?yàn)轭悆?nèi)部是用數(shù)組保存元素的,所以這里訪問數(shù)組最后一個(gè)元素用length-1
下一個(gè)要實(shí)現(xiàn)的方法是isEmpty,如果棧為空的話,就返回true,否則返回false:
this.isEmpty = function () { return items.length == 0; }
使用isEmpty方法,就能簡單地判斷棧內(nèi)部是否為空。
類似于數(shù)組地length屬性,我們也可以實(shí)現(xiàn)棧地length。
this.size = function () { return items.length; }
因?yàn)闂5貎?nèi)部使用數(shù)組保存元素,所以數(shù)組地length就是棧的長度。
實(shí)現(xiàn)clear方法,clear方法用來清空棧中所有的元素。最簡單的實(shí)現(xiàn)方法是:
this.clear = function () { items = []; }
其實(shí)多次調(diào)用pop方法也可以,但是沒有這個(gè)方法來的簡單快捷。
最后,為了檢查棧里的內(nèi)容,還需要實(shí)現(xiàn)一個(gè)輔助方法:print。它會(huì)把棧里的元素都輸出到控制臺(tái):
this.print = function () { console.log(items.toString()); }
至此,我們就完整地創(chuàng)建了一個(gè)棧!
棧的完整代碼function Stack(){ var items = []; //用來保存棧里的元素 this.push = function (element) { items.push(element); } this.pop = function () { return items.pop(); } this.peek = function () { return items[items.length-1]; } this.isEmpty = function () { return items.length == 0; } this.size = function () { return items.length; } this.clear = function () { items = []; } this.print = function () { console.log(items.toString()); } }使用Stack類
棧已經(jīng)創(chuàng)建好了,我們來測試一下
首先,來初始化Stack類。然后,驗(yàn)證一下棧是否為空
var stack = new Stack(); console.log(stack.isEmpty()); //控制臺(tái)輸出true
接下來,往棧里面添加一下元素:
stack.push(5); stack.push(8);
如果調(diào)用peek方法,很顯然將會(huì)輸出8,因?yàn)樗菞m數(shù)脑兀?/p>
console.log(stack.peek()); //控制臺(tái)輸出8
再添加一個(gè)元素:
stack.push(11); console.log(stack.size()); //控制臺(tái)輸出3
我們往棧里又添加了11。如果調(diào)用size方法,輸出為3,因?yàn)闂@镉腥齻€(gè)元素(5,8和11)。如果這時(shí)候調(diào)用isEmpty方法,會(huì)看到輸出了false(因?yàn)榇藭r(shí)棧不為空)。最后,再來往里面添加一個(gè)元素:
stack.push(15);
然后,調(diào)用兩次pop方法從棧里移除兩個(gè)元素:
stack.pop(); stack.pop(); console.log(stack.size()); //控制臺(tái)輸出2 stack.print(); //控制臺(tái)輸出[5,8]
到這里,整個(gè)棧的功能測試完成。
用棧來解決問題使用棧來完成進(jìn)制轉(zhuǎn)換。
現(xiàn)實(shí)生活中,我們主要用10進(jìn)制,但在計(jì)算科學(xué)中,二進(jìn)制非常重要,因?yàn)橛?jì)算機(jī)里所有的內(nèi)容都是用二進(jìn)制數(shù)字0和1來表示的。大學(xué)的計(jì)算機(jī)課都會(huì)先教進(jìn)制轉(zhuǎn)換。以二進(jìn)制為例:
function divideBy2 (decNumber) { var remStack = new Stack(), rem, binaryString = ""; while (decNumber>0) { //{1} rem = Math.floor(decNumber % 2); //{2} remStack.push(rem); //{3} decNumber = Math.floor(decNumber / 2); //{4} } while (!remStack.isEmpty()) { //{5} binaryString += remStack.pop().toString(); } return binaryString; }
這段代碼里,當(dāng)結(jié)果滿足和2做整除的條件時(shí),(行{1}),我們會(huì)獲得當(dāng)前結(jié)果和2的余數(shù),放到棧里(行{2}、{3})。然后讓結(jié)果和2做整除(行{4})
注:JavaScript有數(shù)字類型,但是它不會(huì)區(qū)分時(shí)整數(shù)還是浮點(diǎn)數(shù)。因此,要使用Math.floor函數(shù)讓除法的操作僅返回整數(shù)部分。
最后,用pop方法把棧中的元素都移除,把出棧的元素連接成字符串(行{5})。
測試一下:
console.log(divideBy2(520)); //輸出1000001000 console.log(divideBy2(10)); //輸出1010 console.log(divideBy2(1000)); //輸出1111101000
接下來,可以很容易的修改上面的算法,使它能夠把十進(jìn)制轉(zhuǎn)化為任何進(jìn)制。除了讓十進(jìn)制數(shù)字和2整除轉(zhuǎn)成二進(jìn)制數(shù),還可以傳入其他任意進(jìn)制的基數(shù)作為參數(shù),就像下面的算法這樣:
function baseConverter (decNumber, base) { var remStack = new Stack(), rem, baseString = ""; digits = "0123456789ABCDEF"; //{6} while (decNumber>0) { rem = Math.floor(decNumber % base); remStack.push(rem); //{3} decNumber = Math.floor(decNumber / base); } while (!remStack.isEmpty()) { baseString += digits[remStack.pop()]; //{7} } return baseString; }
在將十進(jìn)制轉(zhuǎn)成二進(jìn)制時(shí),余數(shù)是0或1;在將十進(jìn)制轉(zhuǎn)成八進(jìn)制時(shí),余數(shù)時(shí)0-8之間的數(shù);但是將十進(jìn)制轉(zhuǎn)成十六進(jìn)制時(shí),余數(shù)時(shí)0-9之間的數(shù)字加上A、B、C、D、E、F(對(duì)應(yīng)10、11、12、13、14和15)。因此,需要對(duì)棧中的數(shù)字做個(gè)轉(zhuǎn)化才可以(行{6}、{7})。
來測試一下輸出結(jié)果:
console.log(baseConverter(1231,2)); //輸出10011001111 console.log(baseConverter(1231,8)); //輸出2317 console.log(baseConverter(1231,16)); //輸出4CF
顯然是正確的。
小結(jié)我們用js代碼自己實(shí)現(xiàn)了棧。并且通過進(jìn)制轉(zhuǎn)換的例子來實(shí)際應(yīng)用了它。棧的應(yīng)用實(shí)例還有很多,比如平衡圓括號(hào)和漢諾塔。感興趣可以自行百度去了解
原文鏈接:行無忌的成長小屋:如何用JavaScript手動(dòng)實(shí)現(xiàn)一個(gè)棧
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/95481.html
摘要:翻譯瘋狂的技術(shù)宅原文許多前端開發(fā)人員都在用為他們的網(wǎng)站設(shè)計(jì)樣式。一些人喜歡在中添加一些自己偏好的樣式,我也一樣。我認(rèn)為這是令人難以置信和奇怪的。不同的瀏覽器為表單元素和按鈕設(shè)置了不同的邊框樣式。這種風(fēng)格的問題是它的特異性低。 翻譯:瘋狂的技術(shù)宅原文:https://medium.freecodecamp.o... 許多前端開發(fā)人員都在用 Normalize 為他們的網(wǎng)站設(shè)計(jì)樣式。一些...
摘要:格式化安裝插件如果題主認(rèn)真讀了的的話,應(yīng)該可以寫出下面的配置了。用來格式化和提示格式錯(cuò)誤。在編碼過程中提示格式錯(cuò)誤,養(yǎng)成良好的編碼習(xí)慣。 前言 感覺搭建一個(gè)舒服的前端開發(fā)環(huán)境,十分的重要定制化的格式化,編輯器自帶的格式化各種報(bào)錯(cuò),手動(dòng)改真的會(huì)死人,因此搭建一個(gè)編輯器環(huán)境必不可少,現(xiàn)在要講的是vscode中如何定制vue vs code的配置文件: showImg(https://seg...
摘要:此事件隊(duì)列的美妙之處在于它只是函數(shù)等待被調(diào)用和移動(dòng)到調(diào)用棧的一個(gè)臨時(shí)存放區(qū)域。在事件循環(huán)不斷監(jiān)視調(diào)用棧是否為空現(xiàn)在確實(shí)是空的時(shí)候調(diào)用創(chuàng)建一個(gè)新的調(diào)用棧來執(zhí)行代碼。在執(zhí)行完之后進(jìn)入了一個(gè)新的狀態(tài)這個(gè)狀態(tài)調(diào)用棧為空事件記錄表為空事件隊(duì)列也為空。 這篇文章是對(duì)個(gè)人認(rèn)為講解 JavaScript 事件循環(huán)比較清楚的一篇英文文章的簡單翻譯,原文地址是http://altitudelabs.com...
摘要:變量作者簡介是推出的一個(gè)天挑戰(zhàn)。這是一個(gè)的新特性,和目前都還不支持。命名寫法是變量名,在引用這個(gè)變量時(shí)寫法是變量名。如何用改變屬性值在中即代表文檔根元素。 Day03 - CSS 變量 作者:?liyuechun 簡介:JavaScript30 是 Wes Bos 推出的一個(gè) 30 天挑戰(zhàn)。項(xiàng)目免費(fèi)提供了 30 個(gè)視頻教程、30 個(gè)挑戰(zhàn)的起始文檔和 30 個(gè)挑戰(zhàn)解決方案源代碼。目的是...
摘要:前端日報(bào)精選精讀與提案知乎專欄第期認(rèn)識(shí)引擎記錄一次利用工具進(jìn)行性能優(yōu)化的真實(shí)案例簡書中的使用規(guī)則教程繼承的實(shí)現(xiàn)方法個(gè)人文章中文譯組件渲染性能探索個(gè)人文章周刊第期表單性能的改進(jìn)實(shí)踐知乎專欄簡單可重用的圖表庫知乎專欄 2017-07-08 前端日報(bào) 精選 精讀 TC39 與 ECMAScript 提案 - 知乎專欄【第989期】認(rèn)識(shí) V8 引擎記錄一次利用 Timeline/Perform...
閱讀 1785·2021-11-15 11:37
閱讀 3064·2021-11-04 16:05
閱讀 1925·2021-10-27 14:18
閱讀 2756·2021-08-12 13:30
閱讀 2500·2019-08-29 14:18
閱讀 2086·2019-08-29 13:07
閱讀 2025·2019-08-27 10:54
閱讀 2727·2019-08-26 12:15