JavaScript通过队列和双端队列实现击鼓传花游戏

游戏规则:

        民间击鼓传花游戏,也称传彩球。数人、十数人或数十人围成一个圆圈,把花尽快地传递给旁边的人。某一时刻传花停止,这个时候花在谁手里,谁就退圈、结束游戏。重复该过程,直到只剩一个人(胜利者)。

相信大家小时候都玩过击鼓传花小游戏,那么接下来,我们就代码实现理论与实际相结合。

概念介绍:

        队列(Queue):队列是遵循先进先出(FIFO)原则的一组有序的项。队列在尾部添加新元素,并从顶部移除元素。最新添加的元素必须排队队列中的末尾。像现实生活中的一条单行线,先进来的人会先出去。

        双端队列(Deque):双端队列是一种允许我们从前端和后端同时添加和移除元素的特殊队列。常见应用是存储一系列的撤销操作。像现实生活中排队结账,排在第一位的人会先享受服务,离开后有需要咨询的问题,可以回头插入到第一位,继续询问,排在末尾的人,也可以选择直接离开。由于双端队列同时遵守了先进先出和后进后出原则,可以说它是队列和栈相结合的一种数据结构。

代码实现:

基于数组封装队列类

function Queue() {
  // 属性
  this.items = [];

  // 方法
  // 1.enqueue():将元素加入到队列中
  Queue.prototype.enqueue = (element) => {
    this.items.push(element);
  };

  // 2.dequeue():从队列中删除前端元素
  Queue.prototype.dequeue = () => {
    return this.items.shift();
  };

  // 3.front():查看前端的元素
  Queue.prototype.front = () => {
    return this.items[0];
  };

  // 4.isEmpty:查看队列是否为空
  Queue.prototype.isEmpty = () => {
    return this.items.length == 0;
  };

  // 5.size():查看队列中元素的个数
  Queue.prototype.size = () => {
    return this.items.length;
  };

  // 6.toString():将队列中元素以字符串形式输出
  Queue.prototype.toString = () => {
    let resultString = "";
    for (let i of this.items) {
      resultString += i + " ";
    }
    return resultString;
  };
}

击鼓传花游戏代码实现:

function hotPotato(elementsList, num) {
  const queue = new Queue();
  const elimitatedList = [];

  for (let i = 0; i < elementsList.length; i++) {
    queue.enqueue(elementsList[i]);
  }

  while (queue.size() > 1) {
    for (let i = 0; i < num; i++) {
      queue.enqueue(queue.dequeue());
    }
    elimitatedList.push(queue.dequeue());
  }

  return {
    eliminated: elimitatedList,
    winner: queue.dequeue(),
  };
}

const names = ["summer", "sunny", "jake", "mickael", "winter"];
const result = hotPotato(names, 8);

result.eliminated.forEach((name) => {
  console.log(`${name}在击鼓传花游戏中被淘汰`);
});

console.log(`winner:${result.winner}`);

运行效果图如下:

 

参考书籍:《学习JavaScript数据结构与算法》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值