栈的pop和peek_学习数据结构与算法之栈与队列

本文介绍了数据结构中的栈,强调了栈遵循后进先出(LIFO)原则,并通过JavaScript实现了栈的基本操作:push、pop和peek。此外,还展示了栈在十进制转任意进制转换中的应用,以及栈与队列的区别和队列的实现。
摘要由CSDN通过智能技术生成

起因

最近要准备校招,打开某网站准备开始刷题,发现算法题根本无法动手,于是觉得这块需要恶补。(⊙v⊙)嗯,至少得先知道概念吧。于是翻出了机房里的这本《学习JavaScript数据结构与算法》开始学习程序员的基础知识。这本书用了我最熟悉的JS来实现各种数据结构和算法,而且书很薄,可以说是一本不错的入门教程。虽然我是个前端,但是计算机基础不能丢下。

栈可以理解为一种特殊的数组。遵循后进先出(LIFO)的原则,元素在栈顶添加和删除。生活中常用来比作栈的例子主要是一叠盘子或一堆书,但是我觉得不够形象,因为盘子或书可以从中间被抽走。所以我一般把栈看成弹匣,想象一下子弹被一个个推进弹匣中,比如下图:

c80340fb6a88a2e6102d6eb19e26acef.png

(图片来自谷歌搜索,侵删)

用JavaScript实现栈

声明一个构造函数:

function Stack () {

// 使用数组来保存栈元素

var items = []

}

为栈声明一些方法:

push(elements(s)):添加一个或多个元素到栈顶

pop():删除位于栈顶的元素,并返回该元素

peek():返回栈顶元素

isEmpty():当前栈为空则返回true,否则为false

size():返回栈的元素个数

clear():清空栈

实现push

用数组的push方法向数组末尾添加新元素,实现元素入栈

// 栈顶添加

this.push = function (element) {

items.push(element)

}

实现pop

用数组的pop方法在数组末尾删除一个元素,并返回删除元素,实现元素出栈

// 栈顶删除并返回删除元素

this.pop = function () {

return items.pop()

}

实现peek

栈顶就是数组最后一个元素,使用Array[Array.length - 1]获得

// 返回栈顶元素

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())

}

栈的应用

书上的例子有将十进制转二进制,这里我把后面那个十进制转任意进制的代码贴出来。

十进制转二进制原理很简单:把十进制数不断除以2直到为0,然后把每次的余数拼接到一起就是二进制数。

转其他进制也是类似的方法,只不过是把除以2换成其他数而已。代码如下:

// 把十进制转成任何进制

function BaseConverter (decNumber, base) {

var remStack = new Stack(),

rem,

binaryString = '',

digits = '0123456789ABCDEF'

// 判断十进制数是否为0,把余数推入栈中

while (decNumber > 0) {

rem = Math.floor(decNumber % base)

remStack.push(rem)

decNumber = Math.floor(decNumber / base)

}

// 把栈中的元素拼接打印出来

while (!remStack.isEmpty()) {

binaryString += digits[remStack.pop()]

}

// 返回转换的二进制数

return binaryString

}

这里的decNumber是要转换的十进制数,base是要转换的进制,remStack是上面Stack的实例,在remStack中操作栈的方法。这里的digits是对打印出来的数做一个处理,比如十六进制的数余数会大于9,那么就要用A、B、C、D、E、sF来表示10~15。

栈的学习暂时就这样了,这里贴上代码地址,有兴趣的可以看看:

队列

和栈很类似,只是原则不同,队列是先进先出(FIFO),又称先来先服务。队列在头部删除元素,尾部添加元素。生活中队列的例子就是排队了,这也很容易理解。

用JavaScript实现队列

同样声明构造函数:

function Queue () {

var items = []

}

队列的方法:

enqueue(elements(s)):向队列尾部添加一个或多个元素

dequeue():移除队列头部的元素并返回

front():返回队列头部的元素

其他的和栈一样。

实现enqueue

用push方法推入元素

// 向队列尾部添加元素

this.enqueue = function (element) {

items.push(element)

}

实现dequeue

用shift方法删除第一个数组元素,并返回删除的元素

// 删除队列头部的元素并返回删除元素

this.dequeue = function () {

return items.shift()

}

实现front

直接返回第一个数组元素

// 返回队列头部的元素

this.front = function () {

return items[0]

}

队列的应用

书上有讲优先队列和循环队列的应用,这里就简单讲一下优先队列的原理:

要实现优先队列有两种思路:一是将元素按正确的位置添加到队列中,然后元素正常在队列头部被删除;二是元素在队列尾部不按优先级正常入列,然后按优先级删除对应元素。

书上是按第一种思路实现的优先队列,这里限于篇幅就贴上代码地址:

接下来谈谈循环队列的应用——击鼓传花游戏

function hotPotato (nameList, num) {

var queue = new Queue()

// 参与者的名字入列

for (var i = 0; i < nameList.length; i++) {

queue.enqueue(nameList[i])

}

var eliminated = ''

// 队列中的最后一个人为胜者

while (queue.size() > 1) {

// 按设定的击鼓次数,每个人都从队列头部出列转到队列尾部(模拟传花)

for (var i = 0; i < num; i++) {

queue.enqueue(queue.dequeue())

}

// 到了规定次数后,在队列头部的人(相当于拿到花)被淘汰

eliminated = queue.dequeue()

console.log(eliminated + '在击鼓传花游戏中被淘汰')

}

// 胜者出列并被返回

return queue.dequeue()

}

其中nameList是参与游戏的名字列表,num是击鼓次数。

队列学习就暂时到这里,明天继续学习链表。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值