数据结构学习二(基于JavaScript)----队列

队列是一种“先进先出”的线性表。只允许在队列头部删除元素,尾部添加元素。好像生活中排队购票一样。如下图
在这里插入图片描述

队列的方法

  • enqueue 队列尾部添加一个元素
  • dequeue 队列头部删除一个元素
  • head 返回头部元素
  • size 返回队列大小
  • clear 清空队列
  • isEmpty 判断队列是否为空
  • tail 返回队列尾节点

基于数组实现一个队列

function Queue(){
    var items = [];
    // 队列的方法
    // 向队列尾部添加一个元素
    this.enqueue =function(item){
        items.push(item)
    }
    // 移除队列头部的元素
    this.dequeue = function(){
       return  items.shift();
    }
    //返回队列头部的元素
    this.head = function(){
        return items[0];
    }
    //清空
    this.clear = function(){
        items = [];
    }
    // 判断队列是否为空
    this.isEmpty = function(){
        return items.length == 0;
    }
    // 返回队列尾部元素
    this.tail = function(){
        return items[items.length-1];
    } 
    //返回队列大小
    this.size = function(){
        return items.length;
    }
}

##案例练习
1、约瑟夫环

题目要求:有一个数组,存放0-100,每隔两个元素删除一个,求最后一个删除的元素。

思路:
先将这100个数放入队列。使用while循环,while循环终止的条件是队列里只有一个元素。使用index变量从0开始计数,算法如下:
a、从队列头部删除一个元素,index+1
b、如果index%3 == 0 ,就说明这个元素时需要删除的元素,如果不等于0,就是不需要删除的,则把它添加到队列的尾部。

// 约瑟夫环
function del_ring(arr_list){
    var queue = new Queue();
    // 把数组的元素放入队列
    for (let i = 0; i< arr_list.length; i++) {
      queue.enqueue(arr_list[i]);
    }
    var index = 0 ;
    while(queue.size()!=1){
        var item = queue.dequeue();//弹出一个元素
        index++;
        if(index%3!=0){//每隔两个删除一个,那么不是被删除的元素就放回队尾
            queue.enqueue(item)
        }
    }
    return queue.head();
}

测试代码:

 //准备好数据
    var arr= [];
    for (let i = 0; i < 100; i++) {
       arr.push(i)
    }
    console.log(del_ring(arr));//90

2、斐波那契数列
题目:

使用队列计算斐波那契数列的第n项。

思路:
斐波那契数列的前两项是1、1,后面的每一项都是前面两项的和,即f(n) = f(n-1)+f(n-2);
先将两个1添加到队列中,使用while循环,用index计数,循环终止条件是index<n-2;
a、使用dequeue方法从队列头部删除一个元素,该元素为del_item.
b、使用head方法获取队列头部的元素,该元素为head_item.
c、del_item + head_item = next_item,将next_item放入数列。(只能从尾部添加元素)
d、index+1
当循环结束时,队列里有两个元素,先用dequeue删除头部元素,剩下的就是答案。

  function fibonaqi(n){
        // 前两项都是 1 
        if(n==1||n==2){
            return 1;
        }
        let queue = new Queue();
        let index = 0;
        //先放入前面两个
        queue.enqueue(1);
        queue.enqueue(1);
        while(index<n-2){
            //出队列一个元素
            let del_item = queue.dequeue();
            // 队列头部元素
            let head_item = queue.head();
            let next_item = del_item + head_item;
            // 结果放入队列
            queue.enqueue(next_item);
            index++;
        }
        queue.dequeue();
        return queue.head();
    }
    console.log(fibonaqi(1));//1
    console.log(fibonaqi(3));//2
    console.log(fibonaqi(4));//3
    console.log(fibonaqi(5));//5

3、使用两个队列实现栈
思路:队列是先进先出,栈是先进后出。
两个队列分别命名为queue_1 queue_2 实现方式如下
a、push方法 如果两个队列都为空,那么默认先queue_1里添加数据,如果有一个不为空,则向这个不为空的队列里添加元素。
b、top方法 两个队列都为空或者有一个不为空,只需要返回不为空的队列的尾部元素即可。
c、pop方法 pop要删除的是栈顶,但是这个栈顶元素是队列的尾部元素。每一次做pop操作时,将不为空的队列里的元素依次删除并放入到另外一个队列中,直到这个队列中只有一个元素
d、 删除这个元素,其余的元素都跑到之前为空的队列里了。

function QueueStack(){
    var queue_1 = new Queue();
    var queue_2 = new Queue();
    var data_queue = null;//存放数据的队列
    var empty_queue = null;//空队列 备份用

    // 确认哪个队列放数据 哪个队列备份空队列
    var init_queue = function(){
        // 都为空,默认返回queue_1
        if(queue_1.isEmpty()&&queue_2.isEmpty()){
            data_queue = queue_1;
            empty_queue = queue_2;
        }else if(queue_1.isEmpty()){
            data_queue = queue_2;
            empty_queue = queue_1;
        }else{
            data_queue = queue_1;
            empty_queue = queue_2
        }
    }
    // top方法
    this.top = function(){
        init_queue();
        return data_queue.tail();
    }
    // push方法
    this.push = function(item){
        init_queue();
        data_queue.enqueue(item)
    }
    /** pop 弹出栈顶元素 这个栈顶元素就是队列的尾部元素,但是尾部元素是不能删除的。
     * 所以把data_queue里的元素(除了队尾的)都移到empty_queue中
     * 最后删除data_queue的队尾元素并返回。
     * data_queue和empty_queue 交换了身份。 
     * */
    this.pop = function(){
        init_queue();
        while(data_queue.size()>1){
            empty_queue.enqueue(data_queue.dequeue());
        }
        return data_queue.dequeue();
    }
}  

var queueStack = new QueueStack();
queueStack.push(3);
queueStack.push(5);
console.log(queueStack.top());//5
queueStack.pop();
console.log(queueStack.top());//3

猜你喜欢

转载自blog.csdn.net/guo187/article/details/87895780