隊列實現(xiàn)棧&棧實現(xiàn)隊列
本文轉載自微信公眾號「神奇的程序員K」,作者神奇的程序員K。轉載本文請聯(lián)系神奇的程序員K公眾號。
前言
給你兩個棧你如何實現(xiàn)一個隊列,給你兩個隊列你如何實現(xiàn)一個棧。
本文就跟大家分享下這兩個問題的解決思路與實現(xiàn)過程,歡迎各位感興趣的開發(fā)者閱讀本文。
問題分析
我們先來看下棧與隊列的特性:
- 棧:最先加入的元素最后出
- 隊列:最先加入的元素最先出
有關棧與隊列的詳細講解請移步我的另一篇文章:數(shù)據(jù)結構:棧與隊列
有了棧與隊列的理論基礎后,我們就可以利用其特性來分析問題了,我們先來看下如何用棧來實現(xiàn)隊列:
- 我們的已知條件只有兩個棧,將這兩個棧進行標識:棧1、棧2
- 執(zhí)行入隊操作時,我們元素放進棧1。
- 執(zhí)行出隊操作時:
- 把棧1的元素壓入棧2
- 棧2頂部元素出棧
上述思路中,我們用棧1來存儲元素,我們知道棧的規(guī)則是先進后出,因此我們將棧1的元素壓入棧2后,將棧2元素出棧時,剛好符合隊列的特性。
接下來,我們來看下如何用隊列來實現(xiàn)棧:
- 同樣的,我們的已知條件有兩個隊列,將這兩個隊列進行標識:隊列1,隊列2
- 執(zhí)行入棧操作時,將元素放進隊列1
- 執(zhí)行出棧操作時:
- 如果隊列2為空,我們將隊列1中除隊首外的元素放進隊列2
- 如果隊列2不為空,我們將隊列2的元素放進隊列1
- 隊列1元素出隊
上述思路中,我們將元素都放入了隊列1,出棧時,我們只保留隊列1的隊首元素,其他元素全部放入了隊列2,隨后將隊列2的元素又放回了隊列1,最后將隊列1的元素出隊,經(jīng)過我們的這番倒騰后,剛好符合了棧的特性。
實現(xiàn)代碼
經(jīng)過上述分析,我們有了實現(xiàn)思路,接下來我們就將上述思路轉化為具體的代碼,下述代碼中將引入我們之前寫好的隊列與棧的實現(xiàn)代碼,對此不了解的開發(fā)者請移步我的另外兩篇文章:數(shù)組實現(xiàn)棧與對象實現(xiàn)棧、隊列與雙端隊列的實現(xiàn)
棧實現(xiàn)隊列
- 創(chuàng)建StacksAndQueues類文件,聲明解決本文問題所需要的變量
- // 棧與隊列的相關操作
- import Stack from "../../StackTest/lib/Stack.ts";
- import Queue from "../../QueueTest/lib/Queue.ts";
- export default class StacksAndQueues {
- private firstStacks: Stack;
- private secondStacks: Stack;
- private firstQueues: Queue;
- private secondQueues: Queue;
- constructor() {
- this.firstStacks = new Stack();
- this.secondStacks = new Stack();
- this.firstQueues = new Queue();
- this.secondQueues = new Queue();
- }
- }
- 實現(xiàn)入隊函數(shù)
- // 入隊
- enqueue(key: string | number): void {
- // 入棧1
- this.firstStacks.push(key);
- }
- 實現(xiàn)出隊函數(shù)
- // 出隊
- dequeue() {
- while (!this.firstStacks.isEmpty()) {
- this.secondStacks.push(this.firstStacks.pop());
- }
- if (!this.secondStacks.isEmpty()) {
- // 出棧2
- return this.secondStacks.pop();
- }
- return null;
- }
接下來,我們通過一個例子來驗證下上述代碼能否正常執(zhí)行:
- import StacksAndQueues from "./lib/StacksAndQueues.ts";
- // 用棧實現(xiàn)隊列
- const stacksAndQueues = new StacksAndQueues();
- stacksAndQueues.enqueue(3);
- stacksAndQueues.enqueue(9);
- stacksAndQueues.enqueue(12);
- console.log("出隊", stacksAndQueues.dequeue());
- console.log("出隊", stacksAndQueues.dequeue());
- console.log("出隊", stacksAndQueues.dequeue());
隊列實現(xiàn)棧
- 實現(xiàn)入棧函數(shù)
- // 入棧
- stackPush(key: string | number) {
- // 入隊1
- this.firstQueues.enqueue(key);
- }
- 實現(xiàn)出棧函數(shù)
- // 出棧
- stackPop() {
- if (this.firstQueues.isEmpty()) {
- return null;
- }
- // 隊列2為空
- if (this.secondQueues.isEmpty()) {
- while (this.firstQueues.size() != 1) {
- // 將隊列1除隊首外的元素放進隊列2
- this.secondQueues.enqueue(this.firstQueues.dequeue());
- }
- }
- // 隊列2不為空
- while (!this.secondQueues.isEmpty()) {
- // 將隊列2的元素放進隊列1
- this.firstQueues.enqueue(this.secondQueues.dequeue());
- }
- // 隊列1出隊
- return this.firstQueues.dequeue();
- }
- 接下來,我們通過一個例子來驗證下上述代碼能否正常執(zhí)行:
- // 隊列實現(xiàn)棧
- stacksAndQueues.stackPush(3);
- stacksAndQueues.stackPush(9);
- stacksAndQueues.stackPush(12);
- console.log("出棧", stacksAndQueues.stackPop());
- console.log("出棧", stacksAndQueues.stackPop());
- console.log("出棧", stacksAndQueues.stackPop());
代碼地址
本文實現(xiàn)代碼的完整地址如下:
- StacksAndQueues.ts