首页 > 编程语言 >【前端算法学习】数据结构之“栈”

【前端算法学习】数据结构之“栈”

时间:2023-05-26 15:14:42浏览次数:44  
标签:前端 number pop 算法 num ._ push 数据结构 stack

JS中最棒的数据结构:数组

数组是计算机科学中最常用的数据结构。我们知道, 可以在数组的任意位置上删除或添加元素。然而,有时候我们还需要一种在添加或删除元素时有更多控制的数据结构。有两种数据结构类似于数组,但在添加和删除元素时更为可控。它们就是 栈和队列

​ 要开始学习算法,我们务必要学会数组的使用方法。这位博主已经列出了非常详细的数组方法的使用:点击查看

​ 在JS中,我们通过pushpop方法,就能用数组来模拟栈。

什么是栈?

​ 栈是一种遵从后进先出(LIFO)原则的有序集合。新添加的或待删除的元素都保存在栈的 末尾,称作栈顶,另一端就叫栈底。在栈里,新元素都靠近栈顶,旧元素都接近栈底。

​ 在现实生活中也能发现很多栈的例子。例如,下图里的一摞书或者餐厅里堆放的盘子。

JS中如何实现栈?

​ 我们在第一节说过,在JS中,我们通过 push 和 pop 方法,就能用数组来模拟栈。,所以我们就可以push操模拟入栈pop模拟出栈,而数组,就是我们的栈

下面我用TS,创建了一个Stack类,包括了栈常见的一些操作,例如入栈、出栈等等;可以看到我们是使用数组的方法来模拟栈的操作的。

class Stack {
  items: number[] = []

  // 入栈
  _push(element: number): void {
    this.items.push(element)
  }

  // 出栈
  _pop(): number | undefined {
    return this.items.pop()
  }

  // 返回栈顶元素
  _peek(): number {
    return this.items[this._size() - 1]
  }

  // 判断栈是否为空
  _isEmpty(): boolean {
    return this.items.length === 0
  }

  // 清空栈
  _clear(): void {
    this.items = []
  }

  // 返回栈的长度
  _size(): number {
    return this.items.length
  }

  // 打印栈
  _print(): void {
    console.log(this.items.toString())
  }
}

栈的简单应用

​ 在我们了解过栈的概念之后,我们来学习如何简单的使用栈

​ 首先,我们需要初始化一个栈。然后,验证一下栈是否为空(输出是true,因为还没有往 栈里添加元素)。

const stack = new Stack(); 

console.log(stack._isEmpty); // true

​ 接下来,往栈里添加一些元素(这里我们添加数字5和8;你可以添加任意类型的元素):

    stack._push(5);
    stack._push(8);

如果调用peek方法,将会输出8,因为它是往栈里添加的最后一个元素:

 console.log(stack._peek()];//输出:8

再添加一个元素:

stack._push(11);

console.log(stack._size()); //输出:3

最后, 我们再添加一个元素:

stack._push(15);

下图描绘了目前为止我们对栈的操作,以及栈的当前状态:

然后,调用两次pop方法从栈里移除2个元素:

stack._pop();
stack._pop(); 
console.log(stack._size()); //输出: 2 
stack._print() //输出: 5 8

在两次调用pop方法前,我们的栈里有四个元素。调用两次后,现在栈里仅剩下5和8了。下图描绘这个过程的执行:

到此为止,我们模拟了栈的操作,也明白了栈在入栈、出栈的执行逻辑,下面我们就可以用栈进行一些简单的需求实现。

利用栈,实现进制转换

在我们简单了解过栈之后,让我们来实现一些需求场景吧!

实现二进制转换

//利用 Stack类 实现二进制转换
function decimalToBinary(num: number): string {
  const stack = new Stack()
  // 余数
  let rem: number
  // 二进制数
  let binaryString = ''
  // 除以 2 取余数,直到商为 0
  // 余数入栈,然后出栈,得到的就是二进制数
  while (num > 0) {
    rem = Math.floor(num % 2)
    stack._push(rem)
    num = Math.floor(num/2)
  }
  while(!stack._isEmpty()){
    binaryString += stack._pop()
  }
  return binaryString
}

const binary = decimalToBinary(10)
console.log(binary) // 输出:1010

实现多进制转换

在上面的基础上,我们可以通过同时传入需要转换的进制位数,实现不限于二进制的进制转换

// 利用 Stack 转任意进制
function baseConverter(num: number, base: number): string {
  const stack: Stack = new Stack()
  const digits: string = '0123456789ABCDEF'
  let rem: number
  let basedString = ''
  while (num > 0) {
    rem = Math.floor(num % base)
    stack._push(rem)
    num = Math.floor(num / base)
  }
  stack._print()
  while (!stack._isEmpty()) {
    basedString += digits[stack._pop() as number]
  }
  return basedString
}

const basedString = baseConverter(10, 16)
console.log(basedString) // 输出:A

小结

通过本章,我们学习了栈这一数据结构的相关知识。我们用TS代码自己实现了栈,还讲解了如何用push和pop往栈里添加和移除元素。另外还用进制转换这个例子讲解了如何使用栈。

下一章将要学习队列。它和栈有很多相似之处,但有个重要区别,队列里的元素不遵循后进先出原则。

标签:前端,number,pop,算法,num,._,push,数据结构,stack
From: https://www.cnblogs.com/mosaicMask/p/17434778.html

相关文章

  • 有关素数的基础算法 素性测试 埃氏筛法
    所谓素数,是指恰好有两个约数的正整数。因为n的约数都小于n,所以只需要检查2~ n-1之间所有的整数是否整除n就能判定n是不是素数。如果d是n的约数,那么n/d也是n的约数。由n=d*n/d可知min(d,n/d)  ,所以只需要检查2~ 之间的所有整数就足够了。同理可知,整数分解和约数枚举都......
  • 前端开发:基本技能和最佳实践
    介绍前端开发在创建沉浸式和用户友好的Web体验方面起着至关重要的作用。随着对动态和响应式网站的需求不断增长,前端开发人员需要了解最新的工具、技术和最佳实践。了解前端开发在本节中,我们将概述前端开发及其在创建引人入胜的用户界面方面的重要性。我们将解释HTML、CSS和Jav......
  • 算法学习记录(模拟枚举贪心题单):四舍五入(未AC)
    题目链接https://ac.nowcoder.com/acm/contest/20960/1004题目分析注意当第i位为9是,此时进位就是0,但是0<5,所以就不能再用i+1进行判断了。所以对于这种情况可以再添加一个其他变量。未AC代码//主要解决问题,因为使用i+1去判断是否要进位的//逢9进位后就会变成0,那么第i+1位......
  • 算法学习 | 从几个有趣的故事说起,聊聊里面的算法
    前言提到故事我就来劲头了。一方面,我喜欢读故事、讲故事、搜集故事,另一方面,用讲故事的方式会为学习增加一些趣味性,有兴趣可以帮助坚持下去。下面要介绍的故事,有些大家应该不陌生。我之前有读到过,但是没有认真的研究过,有种熟悉的陌生感。今天分享读了的故事、研究了的解题过程、顺便......
  • redis 数据结构
    数据结构预算法最难啃,并且redis底层是c,需要熟悉c才好根据源码分析。先占坑吧SDSredis的String的数据结构,全称为简单动态字符串,simpledynamicstring,redis是c编写的,为什么不用c语言的字符串类型呢,肯定是为了优化性能而自定义的一种数据类型举个简单的例子:c获取字符串......
  • 算法之常见排序算法-冒泡排序、归并排序、快速排序
    对于编程中琳琅满目的算法,本人向来是不善此道也不精于此的,而说起排序算法,也只是会冒泡排序。还记得当初刚做开发工作面试第一家公司时,面试官便让手写冒泡排序(入职之后才知道,这面试官就是一个冒泡排序"病态"爱好者,逢面试必考冒泡排序-__-)。后来看吴军的一些文章,提到提高效率的关键就......
  • 16 张图解带你掌握一致性哈希算法
    https://developer.huawei.com/consumer/cn/forum/topic/0203810951415790238发表于2022-02-2414:258571查看摘要:一致性哈希是什么,使用场景,解决了什么问题?本文分享自华为云社区《16张图解|一致性哈希算法》,作者:小林coding。如何分配请求?大多数网站背后肯定不是只有......
  • Algorithm_02--C#排序算法(升序)
    (升序)算法原理:通过重复比较和交换,使较大的元素逐渐“浮”到数组后面。具体步骤:1.比较相邻元素,如果第一个比第二大,就交换它们两个。2.对每一对相邻元素作同样的工作,从开始第一到结尾的最后一对。这样再最后的元素应该会是最大数。3.针对所有的元素重复以上的步骤,除了最后一个。......
  • 哈希算法之md5和sha1
    MD5(MessageDigestAlgorithm5)和SHA1(SecureHashAlgorithm1)都是常见的哈希算法,用于生成哈希值。然而,它们有一些区别。哈希长度:MD5生成的哈希值长度为128位(16字节),而SHA1生成的哈希值长度为160位(20字节)。SHA1相对于MD5具有更大的哈希长度,因此具有更低的碰撞概率。安全性:MD5......
  • 基于TPC算法的WSN网络资源分配matlab仿真
    1.算法仿真效果matlab2022a仿真结果如下:2.算法涉及理论知识概要一个移动通信系统面临的主要问题有三个:由哪些资源组成,资源如何分配?这些资源如何组织形成一个网络,网络架构是什么样子的?各网络组成部分之间如何进行信息交互?资源及资源分配、网络架构、信息交互是移动通信系统运行......