栈和队列

数组是一种线性结构,可在数组的任意位置插入和删除数据,而栈和队列就是比较常见的受限的线性结构。

后进先出,限制是仅允许在表的一端进行插入(进栈)和删除(出栈)运算,这一端称为栈顶,另一端称为栈底。

栈结构面试题

有六个元素6,5,4,3,2,1的顺序进栈(并不是一次性,可以一边入栈一边出栈),问下列哪一个不是合法的出栈序列(C)?
A. 5,4,3,6,1,2 B.4 5 3 2 1 6 C.3 4 6 5 2 1 D.2 3 4 1 5 6
解法:1.把脖子右转90度,自己观察

代码实现栈

栈常见的操作:
push(element):添加一个新元素到栈顶位置;
pop():移除栈顶的元素,同时返回被移除的元素;
peek():返回栈顶的元素,不对栈做任何修改(该方法不会移除栈顶的元素,仅仅返回它);
isEmpty():如果栈里没有任何元素就返回true,否则返回false;
size():返回栈里的元素个数。这个方法和数组的length属性类似;
toString():将栈结构的内容以字符串的形式返回。

  1. 基于数组
function Stack(){
  //栈中的属性
  this.items = []

  // 栈的相关操作
  // 1.将元素压入栈
  this.push=function(item){
    this.items.push(item)
  }
  // 2.从栈中取出元素
  this.pop = function(){
    return this.items.pop()
  }
  // 3.查看一下栈顶元素
  Stack.prototype.peek = function(){
    // 注意:这种直接在原型链上写方法,比上面的方式节省内存
    return this.items[this.items.length-1]
  }
  // 4.判断栈是否为空
  Stack.prototype.isEmpty = function(){
    return this.items.length==0
  }
  // 5.获取栈中元素的个数
  Stack.prototype.size = function(){
    return this.items.length
  }
  // 6.toString方法
  Stack.prototype.toString = function(){
    var resString = ''
    for(var i = 0;i < this.items.length;i ++){
      resString += this.items[i]+' '
    }
    return resString
  }
}
  1. 基于链表(性能与基于数组相差不大)

栈的应用

  1. 十进制转二进制
function dec2bin(decNumber){
  var stack = new Stack()
  while(decNumber>0){
    stack.push(decNumber % 2)
    decNumber = Math.floor(decNumber/2)
  }
  var binNumber = ''
  while(!stack.isEmpty()){
    binNumber += stack.pop()
  }
  return binNumber
}

队列

先进先出,受限之处在于只允许在表的前端进行删除,后端进行插入
应用:
打印队列:计算机打印多个文件的时候,需要排队打印;
线程队列:当开启多线程时,当新开启的线程所需的资源不足时就先放入线程队列,等待CPU处理;

代码实现队列

队列常见的操作:
enqueue(element):向队列尾部添加一个(或多个)新的项;
dequeue():移除队列的第一(即排在队列最前面的)项,并返回被移除的元素;
front():返回队列中的第一个元素——最先被添加,也将是最先被移除的元素。队列不做任何变动(不移除元素,只返回元素信息与Stack类的peek方法非常类似);
isEmpty():如果队列中不包含任何元素,返回true,否则返回false;
size():返回队列包含的元素个数,与数组的length属性类似;
toString():将队列中的内容,转成字符串形式;

  1. 基于数组
function Queue(){
  // 属性
  this.items = []
  // 方法
  Queue.prototype.enqueue=function(element){
    this.items.push(element)
  }
  Queue.prototype.dequeue=function(){
    return this.items.shift()
  }
  Queue.prototype.front=function(){
    return this.items[0]
  }
  Queue.prototype.isEmpty=function(){
    return this.items.length == 0
  }
  Queue.prototype.size=function(){
    return this.items.length
  }
  Queue.prototype.toString=function(){
    var resString = ''
    for(var i = 0;i < this.items.length;i ++){
      resString += this.items[i]+' '
    }
    return resString
  }
}
  1. 基于链表(性能好)

队列面试题

击鼓传花:几个人围成一圈数数,数到某个数字自动淘汰,问最后剩下的人在原来哪一个位置上
function passGame(nameList,num){
  console.log(1)
  // 1.创建一个队列结构
  var queue = new Queue()

  // 2.将所有人一次加入到队列中
  for(var i = 0;i < nameList.length;i ++){
    queue.enqueue(nameList[i])
  }
  
  // 3.开始数数字
  // 不是num的时候,重新加入到队列的末尾
  // 是num这个数字时,将其从队列中删除
  while(queue.size!=1){
    for(var j = 0;j < num-1;j ++){
      // num数字之前的人重新放到队尾
      queue.enqueue(queue.dequeue())

    }
    queue.dequeue()
  }  
  // 获取剩下的那个人
  console.log(queue.size());
  var endName = queue.front()
  console.log(endName)
  return nameList.indexOf(endName)
}

优先级队列

优先级队列需要考虑的问题:

  • 每个元素不再只是一个数据,而且包含数据的优先级
  • 在添加方式中,根据优先级放入正确的位置

优先级队列的应用

  • 机场的登场顺序
  • 医院的候诊室
  • 计算机中,可通过优先级队列排序线程执行的顺序

优先级队列的实现

function PriorityQueue() {
  // 类的内部再封装一个类
  function QueueElement(element, priority) {
    this.element = element
    this.priority = priority
  }
  // 属性
  this.items = []
  // 方法
  PriorityQueue.prototype.enqueue = function (element, priority) {
    // 1、创建QueueElement对象
    var newElement = new QueueElement(element, priority)
    var len = this.items.length
    // 2.判断队列是否为空
    if (len == 0) {
      this.items.push(newElement)
    } else {
      var added = false
      // 该变量用来记录是否前面已找到插入位置
      for (var i = 0; i < len; i++) {
        if (this.items[i].priority > priority) {
          this.items.splice(i, 0, newElement)
          added = true
        }
      }
      if(!added){
        this.items.push(newElement)
      }
    }
  }
  
  PriorityQueue.prototype.dequeue = function () {
    return this.items.shift()
  }
  Queue.prototype.front = function () {
    return this.items[0]
  }
  PriorityQueue.prototype.isEmpty = function () {
    return this.items.length == 0
  }
  Queue.prototype.size = function () {
    return this.items.length
  }
  PriorityQueue.prototype.toString = function () {
    var resString = ''
    for (var i = 0; i < this.items.length; i++) {
      resString += this.items[i] + ' '
    }
    return resString
  }
} 

用两个栈实现一个队列

思想:
入队过程:将元素放入 inStack 中。
出队过程:
outStack 不为空:弹出元素
outStack 为空:将 inStack 元素依次弹出,放入到 outStack 中(在数据转移过程中,顺序已经从后入先出变成了先入先出)

var inStack = [], outStack = []
function push(node) {
  inStack.push(node)

}
function pop() {
  if(outStack.length){
    return outStack.pop()
    
  }else{
    while(inStack.length){
      outStack.push(inStack.pop())
    }
    return outStack.pop()
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值