【在厨房想30天的演算法】Day 08 资料结构:堆叠 Stack

Aloha~!我是少女人妻 Uerica!有天地方角头米饭,蒸笼帮的包子、馒头、肉粽起了争执,米饭米口众多出手又凶狠,很快打得包子馒头满地找牙,害怕的肉粽被逼到角落,立刻将衣服扒开说:我是卧底!


好的~终於来到第 8 天了,今天要来聊一下资料结构中常见的堆叠了!

堆叠 (Stack)

堆叠是一种由下往上的储存资料,且只能从最新的资料开始存取。可以想像如同堆放在桌上的文件,先放的会在最下方,最新的在最上方,而拿取时也只能从最上方开始操作。

堆叠图

堆叠的定义与特性

像这样的资料存取方式,又称「後进先出」(LIFO, Last-in-First-out),或「先进後出」(FILO, First-in-Last-out)。这样的好处是能确保存取的资料都是维持在最新的状态,但因资料存取都只能从最新的元素开始操作,所以若要存取较旧的元素就需要将上方元素一个个取出才行。

vyxQBKM

  • 优点
    • 保持存取资料都是最新的
    • 新增资料快速
  • 缺点
    • 插入或删除费时
    • 越接近第一笔资料越难取得

常见的基本操作

push:将最新的元素推入资料结构中。

a6JVVuk

pop:将最新加入的元素移出资料结构。

T01emTq

peek:在不将资料推出堆叠的情况下得知最新的资料元素。

oj89PLs

size: 回传堆叠里的资料元素数量 (资料长度)

MJGYGrI

来!实作

一般的程序语言都有提供内建的堆叠 (Stack),但 JavaScript 没有,不过在阵列中有些雷同的特性,所以就直接用 JavaScript 阵列与阵列提供的方法来实作看看吧!

//建构一个 Stack 类别,并将其储存的资料 elements 的型态宣告为阵列。
class Stack {
    
    constructor () {
        this.elements = [];
    }

    //使用 JavaScript Array 提供的方法 push()
    push(element) {
        this.elements.push(element);
    }

    //使用 JavaScript Array 提供的方法 pop()
    //如果堆叠内是空的回传 "没有资料元素"
    pop() { 
        if(this.elements.length === 0) return "没有资料元素"; 
        else return this.elements.pop();
    }

    //在不取出的情况下,得知最新资料元素的值。
    //一样使用阵列特性取最後一个的索引值。
    peek() {
        return this.elements [ this.elements.length - 1 ];
    }

    //使用阵列提供的 length 属性,来得知目前资料的长度
    size() {
        return this.elements.length;
    }
}

建立实体,来将文字反转吧

function reverse(str){

     // 创建一个 stack,并宣告一个空字串
     let stack = new Stack();
     let reversedStr = "";
     let i = 0;  

     //利用 while 回圈将所有字元依序推入堆叠中
     while (i !== str.length) {
         stack.push(str.charAt(i));
         i++;
     }
   
     //用回圈一个个取出再存入字串中
     while (stack.size() !== 0) {
         reversedStr += stack.pop();
     }  

     //回传反转後的字串.
     return reversedStr;
}

console.log(reverse('aholA')) //Aloha


关於堆叠的时间复杂度

由於堆叠的 push 或 pop 都是从最新资料推入或取出,此部分的时间复杂度是 O(1),但若是有搬移资料元素,或删除某一资料元素的话,时间复杂度是 O(n)

参考资料:

用 JavaScript 学习资料结构和演算法:堆叠(Stack)篇
JavaScript 学演算法(六)- 堆叠 & 伫列
基本资料结构
Reverse a String with a Stack in JavaScript


感谢阅读!今天就先到这边啦~话说肉粽虽然逃过一劫,但他家人硷粽可就没这麽幸运了~明天见!掰掰~


<<:  Day 8 常利用的 Docker 指令

>>:  Day 9 - 解密 Order API 回传的 Message 字串

[Day 15] Facial Recognition - Eigenfaces

有兴趣知道特徵脸方法 (Eigenfaces)的基本原理 - 主成分分析 (PCA),推荐你看看这...

从 React 开始,让你的网页material-ui起来 [Day 1] 受众&&环境

------------- 告诫 某天公司电脑以为发文完成就关机 ,结果中断铁人赛---------...

Day 26:开始来学资料系结:事件系结(三)今天的 $event 有型别呢!

昨天我们有稍微提到,使用 $event 的 property 时,要注意大小写的问题,虽然只是轻轻带...

Day4|【Git】用户名称与信箱- Git的初始设定与 config

💡 开始使用 Git 之前,我们需要先设定使用者名称及电子邮件地址。 为什麽需要设定用户名称及 E-...

使用WSL2在Windows下快速打造Linux开发环境(含Docker)

对於习惯使用windows在开发大部分工作的开发者来说,如果想要同时开发适合在Linux-based...