数据结构-栈(Stack)和队列(Queue)的实现以及应用(深入浅出)


栈结构和队列是比较常见的 受限的线性结构

栈(Stack)

栈的特性

  • 限定仅仅在表尾进行插入和删除的操作的线性表,这一端称为栈顶。相对的另一端称之为栈底。
  • 原则:后进先出原则

相关名词

  • 进栈(push):压入
  • 出栈(pop):弹出

生活中的栈

盘子就是一个例子,最先放进去的盘子最后拿走,最后放进去的盘子先拿走。
在这里插入图片描述

栈的实现

栈的常见操作

  • push 压入元素到栈顶
  • pop 弹出栈顶元素
  • peek 返回栈顶的元素
  • isEmpty 判断栈是否为空
  • size 返回栈的元素个数
  • toString 栈结构内容以字符串的形式返回

常见的实现方式有

  • 基于数组的实现
  • 基于链表的实现

此处我们用JS实现栈基于数组的封装作为演示:

//基于数组实现的栈结构
function Stack() {
    //存放元素
    this.items = []
    //将内容压入栈顶
    this.__proto__.push = function (value) {
        this.items.push(value)
    }
    //弹出栈顶的元素
    this.__proto__.pop = function () {
        return  this.items.pop()
    }
    //返回栈的长度
    this.__proto__.size = function () {
        return this.items.length-1
    }
    //判断栈是否为空
    this.__proto__.isEmpty = function () {
        if (this.items.length>0) return false
        return true
    }
    //返回栈顶的元素
    this.__proto__.peek = function () {
        return this.items[this.items.length-1]
    }
    //将栈中的内容以字符串的形式输出
    this.__proto__.toString = function () {
        return this.items.toString()
    }
}
var stack = new Stack()
console.log("判断栈是否为空:",stack.isEmpty());
stack.push("张三")
stack.push("李四")
stack.push("王五")
console.log("判断栈是否为空:",stack.isEmpty());
console.log("返回栈顶的元素:",stack.peek())
console.log("将栈中的内容转换城字符串:",stack.toString());
console.log("弹出栈顶元素:",stack.pop())
console.log("将栈中的内容转换城字符串:",stack.toString());

运行结果:
在这里插入图片描述

栈的应用

  • 十进制数字转换成二进制
function decToBin(dec) {                               
    let decNumber = dec                                
    let stack = new Stack()                            
    let binString = ""                                 
                                                       
    while(decNumber>=1){                               
        stack.push(decNumber%2)                        
        decNumber = Math.floor(decNumber/2)            
    }                                                  
    while (!stack.isEmpty()){                          
        binString += stack.pop()                       
    }                                                  
    return binString                                   
}                                                      
                                                       
console.log(decToBin(63))                              

运行结果:
在这里插入图片描述

队列(Queue)

在这里插入图片描述

队列的特性

  • 限定仅在表的前端进行删除,在表的后端进行插入操作,和栈 一样是一种操作受限的线性表。
  • 原则:先进先出原则

生活中的队列

安检的传送带就是队列的例子,先放进的行李会先完成安检
在这里插入图片描述

队列的实现

队列的常见操作

  • enQueue 在队列的末尾添加新的一项
  • deQueue 在队列的头部移出第一项
  • font 返回队列的第一项元素
  • isEmpty 判断队列是否为空
  • size 返回队列的元素个数
  • toString 将队列结构中的内容以字符串的形式返回

常见的实现方式有

  • 基于数组的实现
  • 基于链表的实现

对于队列用链表的实现方式会比较高效,因为对于数组而言,移出数组中的第一个元素后面的元素都需要往前进行移动。链表对于这种操作是比较快捷的不需要进行移动。

此处先用数组的形式进行实现队列,后续将对其进行补充。

//基于数组实现的队列结构
function Queue() {
    //存放元素
    this.items = []
    //在队列尾部添加新的项
    this.__proto__.enQueue = function (value) {
        this.items.push(value)
    }
    //移出队列的第一项
    this.__proto__.deQueue = function () {
       return  this.items.shift()
    }
    //返回队列的长度
    this.__proto__.size = function () {
        return this.items.length-1
    }
    //判断队列是否为空
    this.__proto__.isEmpty = function () {
        if (this.items.length>0) return false
        return true
    }
    //返回队列的第一项
    this.__proto__.font = function () {
        return this.items[0]
    }
    //将队列的内容以字符串的形式输出
    this.__proto__.toString = function () {
        return this.items.toString()
    }
}
var queue = new Queue()
console.log("判断队列是否为空:",queue.isEmpty());
queue.enQueue("张三")
queue.enQueue("李四")
queue.enQueue("王五")
console.log("判断队列是否为空:",queue.isEmpty());
console.log("返回队列的第一项:",queue.font())
console.log("将队列的内容转换城字符串:",queue.toString());
console.log("移出队列的第一项:",queue.deQueue())
console.log("将队列的内容转换城字符串:",queue.toString());

运行结果:
在这里插入图片描述

队列的应用

使用队列结构模拟叫号系统的实现

//模拟叫号系统
function callingSystem(arr) {
    let queue =  new Queue()
    arr.forEach((item,index,array ) => {
        queue.enQueue(item)
    }
    )
    console.log("叫号队列:",queue.toString())
    let flag = setInterval( ()=> {
        if (queue.size() == 0){
            clearInterval(flag)
        }
        let name = queue.deQueue()
        if (!isCallingSuccess()){
            queue.enQueue(name)
            console.log(name,"过号重排")
        }else {
            console.log(name,"叫号成功")
        }
        console.log("叫号队列:",queue.toString())
    },3000)
}
callingSystem(["张三","李四","王五","赵六"])

运行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jaywei.online

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值