數(shù)據(jù)結(jié)構(gòu)之棧和隊列

數(shù)據(jù)結(jié)構(gòu)有許多種吞杭,上篇文章分享的是可以存儲簡單數(shù)據(jù)的列表盏浇,例如待辦事項,購物清單等芽狗。今天要跟大家分享的是兩種非常常見的也必須了解的數(shù)據(jù)結(jié)構(gòu)——棧與隊列绢掰。

棧的定義

什么是棧呢?它是一種“后入先出”的數(shù)據(jù)結(jié)構(gòu),它跟列表一樣滴劲,都是可以用來存儲數(shù)據(jù)攻晒,但是卻要比列表嚴格的多,棧的數(shù)據(jù)只能在棧頂添加或刪除班挖。舉個例子鲁捏,在麥當勞用餐時的那些盤子,撿餐員在拿盤子時聪姿,總是從一摞盤子的最上端拿(棧頂)碴萧,然后放上食品在端給客人,而那些擦餐盤的人末购,也總是在最上面拿起餐盤擦拭后不斷地疊放成一摞餐盤,這里的餐盤就可看成是棧虎谢,數(shù)據(jù)的添加或刪除總是在最上端進行盟榴。下圖展示了棧的構(gòu)成以及簡單的入棧與出棧過程。


圖片來自網(wǎng)絡(luò)

棧的主要操作方法

棧的常用操作就是入棧和出棧婴噩,入棧用的是 push() 方法擎场,出棧用的是 pop() 方法,還有一個方法是 peek() 几莽,該方法可以返回棧頂?shù)脑囟粍h除它迅办,相應(yīng)的 pop() 方法雖然也可以得到棧頂?shù)脑兀珪⑺鼊h除章蚣。

棧的實現(xiàn)

在 JavaScript 中站欺,通常使用數(shù)組來實現(xiàn)棧。下面我們定義一個名為 Stack 的構(gòu)造函數(shù)用來表示棧纤垂。

function Stack() {
  this.dataStore = [];
  this,top = 0;
  this.push = push;
  this.pop = pop;
  this.peek = peek;
}

dataStore 是一個數(shù)組矾策,用來存儲棧中的元素,而變量 top 記錄棧頂?shù)奈恢们吐伲跏嘉恢脼?0贾虽,push 、pop 和 peek 分別對應(yīng)三個方法吼鱼,下面來實現(xiàn)這些方法蓬豁。
首先是 push() ,入棧。

function push() {
  this.dataStore[this.top++] = element;
}

這里 top++ 很有意思菇肃,要知道 + 號在變量后和變量前是不同的地粪,這里的邏輯是,當元素入棧后巷送,變量 top 的值就對應(yīng)當前入棧元素的位置驶忌,然后 top++ ,自增后的值就是下一個元素入棧時的位置了。
接下來是出棧方法 pop() 付魔。

function pop() {
  return this.dataStore[--this.top];
}

前面說了聊品,棧只能在最頂端添加、刪除數(shù)據(jù)几苍,所以我們必須要知道棧頂現(xiàn)在存放的是哪個數(shù)值才能將它刪除翻屈,于是我們使用 top 來標記它的位置,現(xiàn)在出棧妻坝,只需要把指向棧頂?shù)奈恢玫墓?jié)點數(shù)據(jù)拿掉就行了伸眶。
最后一個方法是取棧頂元素的 peek() 方法,相信也不難理解,就把棧頂元素直接返回就行刽宪,注意棧頂元素的位置是第 top - 1 個位置厘贼。

function peek() {
  return this.dataStore[this.top - 1];
}

除了上述的基本操作方法外,還有其它方法可以有作用圣拄。來看下面這兩個方法

function length() {
  return this.top;
}
function clear() {
  this.top = 0;
}

上面的方法一個是可以獲取棧內(nèi)存儲了多少個元素的 length() 方法嘴秸, 另一個是 clear() ,聽名字就知道是把一個棧清空,通過將 top 的值歸零庇谆。

棧的完整代碼

棧的完整代碼以及測試如下

function Stack() {
  this.dataStore = [];
  this,top = 0;
  this.push = push;
  this.pop = pop;
  this.peek = peek;
  this.length = length;
  this.clear = clear;
}

function push() {
  this.dataStore[this.top++] = element;
}

function pop() {
  return this.dataStore[--this.top];
}

function peek() {
  return this.dataStore[this.top - 1];
}

function length() {
  return this.top;
}

function clear() {
  this.top = 0;
}
var s = new Stack();
s.push("xiaoming");
s.push("xiaohong");
s.push("Mike");
console.log("棧的長度為: "+s.length());
console.log(s.peek());   
s.clear();
console.log("當前長度為: "+s.length());

運行結(jié)果為:

棧的長度為: 3
Mike
當前長度為: 0

隊列的定義

隊列是一種與棧截然不同的數(shù)據(jù)結(jié)構(gòu)岳掐,棧的特點是后入先出,最后入棧的元素會優(yōu)先處理而彈出饭耳,而隊列的特點則是先入先出串述,最先進棧的也會最終先出棧,這有點類似于銀行窗口前排隊辦業(yè)務(wù)的人群寞肖,排在最前面的先辦理業(yè)務(wù)纲酗,后面來的就依次排隊。

隊列的主要操作方法

與棧一樣逝淹,隊列也是用數(shù)組來實現(xiàn)耕姊,它的主要操作方法同樣是入隊(enqueue),出隊(dequeue)和讀取隊頭的元素(peek),讀取隊頭元素同樣不會刪除元素,只返回栅葡。此外還有清空隊列元素(clear)和獲取隊列元素個數(shù)(length)茉兰。

隊列的實現(xiàn)

首先定義一個 Queue 類用來表示隊列。

function Queue() {
  this.dataStore = [];     // 存儲隊列元素
  this.enqueue = enqueue;
  this.dequeue = dequeue;
  this.front = front;
  this.back = back;
  this.toString = toString;
  this.empty = empty;
}

接下來實現(xiàn)入隊方法 enqueue() :

function enqueue(element) {
  this.dataStore.push(element);
}

可以看到欣簇,用數(shù)組來實現(xiàn)隊列非常簡單规脸,入隊只需一個 push() 方法即可向隊尾添加元素。

function dequeue() {
  return this.dataStore.shift();
}

shift 是數(shù)組的一個操作方法熊咽,可以將數(shù)組的第一個元素刪除莫鸭。

function front() {
  return this,dataStore[0];
}
function back() {
  return this.dataStore[this.dataStore.length - 1];
}

這兩個分別是讀取隊列的第一個元素和最后一個元素,很簡單横殴,直接返回數(shù)組的第一個元素和最后一個元素即可被因。

function toString() {
  var str = "";
  for (var i = 0; i < this.dataStore.length; i++) {
    str += this.dataStore[i] + "\n";
  }
  return str;
}

這個方法顯示隊列元素卿拴,類似控制臺 console 輸出元素。

function empty() {
  if (this.dataStore.length == 0) {
    return true;
  }
  else {
    return false;
  }
}

這是一個判空方法梨与,每次使用隊列前要判斷是否為空才可進行下一步的操作堕花。

隊列完整代碼及測試

function Queue() {
  this.dataStore = [];     // 存儲隊列元素
  this.enqueue = enqueue;
  this.dequeue = dequeue;
  this.front = front;
  this.back = back;
  this.toString = toString;
  this.empty = empty;
}

function enqueue(element) {
  this.dataStore.push(element);
}

function dequeue() {
  return this.dataStore.shift();
}

function front() {
  return this,dataStore[0];
}
function back() {
  return this.dataStore[this.dataStore.length - 1];
}

function toString() {
  var str = "";
  for (var i = 0; i < this.dataStore.length; i++) {
    str += this.dataStore[i] + "\n";
  }
  return str;
}

function empty() {
  if (this.dataStore.length == 0) {
    return true;
  }
  else {
    return false;
  }
}
var q = new Queue();
q.enqueue("Mike");
q.enqueue("Hello");
q.enqueue("hhhh");
console.log(q.toString());
q.dequeue();
console.log(q.toString());
console.log("隊列的第一個元素是: " + q.front());
console.log("隊列的最后一個元素是: " + q.back());

運行結(jié)果如下:

Mike
Hello
hhhh
Hello
hhhh
隊列的第一個元素是: Hello
隊列的最后一個元素是: hhhh

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市粥鞋,隨后出現(xiàn)的幾起案子缘挽,更是在濱河造成了極大的恐慌,老刑警劉巖呻粹,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件壕曼,死亡現(xiàn)場離奇詭異,居然都是意外死亡等浊,警方通過查閱死者的電腦和手機腮郊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來筹燕,“玉大人伴榔,你說我怎么就攤上這事∽” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵塘安,是天一觀的道長糠涛。 經(jīng)常有香客問我,道長兼犯,這世上最難降的妖魔是什么忍捡? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮切黔,結(jié)果婚禮上砸脊,老公的妹妹穿的比我還像新娘。我一直安慰自己纬霞,他們只是感情好凌埂,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著诗芜,像睡著了一般瞳抓。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上伏恐,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天孩哑,我揣著相機與錄音,去河邊找鬼翠桦。 笑死横蜒,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播丛晌,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼仅炊,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了茵乱?” 一聲冷哼從身側(cè)響起茂洒,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎瓶竭,沒想到半個月后督勺,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡斤贰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年智哀,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片荧恍。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡瓷叫,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出送巡,到底是詐尸還是另有隱情摹菠,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布骗爆,位于F島的核電站次氨,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏摘投。R本人自食惡果不足惜煮寡,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望犀呼。 院中可真熱鬧幸撕,春花似錦、人聲如沸外臂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽专钉。三九已至挑童,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間跃须,已是汗流浹背站叼。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留菇民,地道東北人尽楔。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓投储,卻偏偏與公主長得像,于是被迫代替她去往敵國和親阔馋。 傳聞我的和親對象是個殘疾皇子玛荞,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345

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