博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
javascript的数据结构快速学-栈和队列
阅读量:6221 次
发布时间:2019-06-21

本文共 5438 字,大约阅读时间需要 18 分钟。

准备学习《学习JavaScript数据结构与算法》,自己也开始做一写笔记来记录总结,本文也是仅针对实现方面的总结。

如果出现错误,请在评论中指出,我也好自己纠正自己的错误

author: thomaszhou

栈的实现

栈,其实就是一个数组,但是这是个非常特殊的数组,因为栈有个特性:先进后出,什么意思呢?看着下面的图来讲解。

原谅我是个灵魂画手

  • 栈只有一个开口,这个开口,是进口,也是出口

    • 我们从这个口添加数据,也从这个口取出数据
  • 栈的原则:先进后出

    • 我们依次添加1,2,3进入栈中,那我们取出的第一个值是3,第二个取出的值是2,第三个是1。那如果在取出2的时候,又添加一个数呢?大家可以模拟一下
  • 定义栈类和声明的方法

function Stack() {  //定义栈 的类      var items = [];            this.push = function(elem) {//添加元素        return items.push(elem);      };      this.pop = function() {//弹出元素        return items.pop();      };      this.print = function() { //输出        console.log(items.toString());      };            this.size = function() {//输出栈的长度        return items.length;      };            this.clear = function() {//将栈置为空        return items = [];      };            this.peek = function() {//显示顶层元素        return items[items.length-1]      };            this.isEmpty = function() { // 判断栈是否为空        return items.length === 0;      };}复制代码

栈的测试函数

(function demo1() {  let stack1 = new Stack();  //创建栈  stack1.push(1);  stack1.push(2);  stack1.push(3);  stack1.push(4);  stack1.print();  console.log(stack1.pop());//4  console.log(stack1.peek());// 3  console.log(stack1.isEmpty());// false  stack1.clear();  console.log(stack1.isEmpty());// true})();复制代码
  • 栈的例子:十进制转换为任意进制
function divideBy2(elem, base) {      var str = '',          temp = 0,          arr = new Stack(),//创建栈          baseStr = '0123456789ABCDEF';      while (elem !== 0) {        arr.push(Math.floor(elem % base));//容易漏掉Math.floor()就会造成结果为undefine;        elem = Math.floor(elem / base);        //         //console.log(elem);  测试debug      }      while (!arr.isempty()) {        console.log(arr);        str += baseStr[arr.pop()]; // 字符串也是数组,所有要用baseStr[]。而不能用baseStr()      }      return str;    }        console.log(divideBy2(7, 2));复制代码

队列的实现

(1) 普通队列

  • 队列和栈的不同就在于:
    • 1、栈是先进后出,那就是push和pop方法
    • 2、队列是先进先出,那就是push和shift方法
  • 我们看啊,从右边进去,依次添加1,2,3,4,取出的第一个值是啥?是1,第二个,第三个第四个就是2,3,4.也就是说,我们添加一定是从右边进去,取出一定是从左边出去,也就是上面说的先进先出,先进去的,就先出来
function Queue() {	  let items = [];	  this.enqueue = function(ele) {	    items.push(ele);		};	  this.dequeue = function() {	    return items.shift();		};	  this.front = function() {	    return items[0];		};	  //	下面方法 同 栈	  this.isEmpty = function() {	    return items.length === 0;		};	  this.clear = function() {	    items = [];		};	  this.size = function() {	    return items.length;	  };          this.print = function() {            console.log(items.toString());          }	}复制代码

普通队列的测试函数:

(function queueDemo() {	  var queue = new Queue();	  queue.enqueue(1);	  queue.enqueue(2);	  queue.enqueue(3);	  queue.print();    //1,2,3	  console.log(queue.dequeue()); //1	  console.log(queue.isEmpty()); //false	  console.log(queue.size());    //2	  console.log(queue.front());   //2	  queue.clear();	  console.log(queue.size());  // 0	})();复制代码

(2) 优先队列

优先队列的核心在于设置优先级,队列的每个数据不是单一值,而是一个值和一个优先级id

  • 1、 采用构造函数,构造一个含有element和priority的实例
  • 2、 每次添加实例到队列中,按照优先级的先后插入到队列中(splice方法)
//	优先队列	function PriorityQueue() {	  let items = [];	  function QueueElement(element, priority) {	    this.element = element;	    this.priority = priority;		}	  this.enqueue = function(element, priority) {	    let ele = new QueueElement(element, priority);	    if (this.isEmpty() === true) { // 队列为空,直接push	      items.push(ele);	    }else {	      // 队列不为空,element的优先级priority小的在前面              for (let i = 0; i < items.length; i++) {                if (ele.priority < items[i].priority) {                  items.splice(i, 0, ele);		}else {		//  element的优先级最低的情况-直接push到最后                  items.push(ele);		}		break;              }	    }	  };      this.print = function() {        for (let i = 0; i < items.length; i++) {          console.log(`ele: ${items[i].element},prio: ${items[i].priority}`);        }      };//		其他的方法和普通队列相同      this.dequeue = function() {        return items.shift();      };      this.front = function() {        return items[0];      };           this.isEmpty = function() {        return items.length === 0;      };      this.clear = function() {        items = [];      };      this.size = function() {        return items.length;      };	}复制代码

优先队列测试函数:

(function priQueueDemo() {  var queue = new PriorityQueue();  queue.enqueue(1, 4);  queue.enqueue(2, 7);  queue.enqueue(3, 1);  queue.print();      //	ele: 3,prio: 1	//  ele: 1,prio: 4	//  ele: 2,prio: 7  console.log(queue.dequeue());//QueueElement {element: 3, priority: 1}  console.log(queue.isEmpty());//false  console.log(queue.size());//2  console.log(queue.front());//QueueElement {element: 1, priority: 4}  queue.clear();  console.log(queue.size());// 0})();复制代码

(3)循环队列

循环队列和普通队列的区别:普通队列和循环队列都是后面进一个,前面进一个.不同点就在于,循环队列是要将弹出的元素再返回到尾部再添加进去 核心代码就是queue.enqueue(queue.dequeue())

循环队列的应用-击鼓传花 击鼓传花的游戏都玩过,就是一堆人围一个圈,然后传递花,轮一圈,谁拿到花就淘汰谁(我们的例子是通过设置num来表示一轮传递几个人,算是一个规律性的击鼓传花,如果想实现真正的击鼓传花,那么就设置num为random,然后设置一个范围,就可以了,num = Math.floor(num * Math.random())

  • 所以也只是一个虚拟的游戏
function hotPotato (nameList, num) {  let queue = new Queue(),    len = nameList.length;  for (let i = 0; i < len; i++) {    queue.enqueue(nameList[i]);  }  while (queue.size() > 1) {// 队列最后剩下一个    for (let i = 0; i < num; i++) {      queue.enqueue(queue.dequeue());// 循环队列的核心    }    console.log(`${queue.dequeue()}被淘汰`);  }  console.log(`${queue.dequeue()}胜利`);//队列的最后一个值}let arr = ['thomas1', 'thomas2', 'thomas3', 'thomas4', 'thomas5'];hotPotato(arr, 2);//thomas3被淘汰//thomas1被淘汰//thomas5被淘汰//thomas2被淘汰//thomas4胜利复制代码

转载地址:http://serja.baihongyu.com/

你可能感兴趣的文章
Shortest Distance from All Buildings
查看>>
rdm代码网址
查看>>
乘方取模计算(模幂计算)
查看>>
Ubuntu安装PyCharm
查看>>
如何将CTB词性标签映射为universalPOs标签
查看>>
BZOJ5299:[CQOI2018]解锁屏幕(状压DP)
查看>>
Mac OSX 快捷键&命令行总览
查看>>
c++面试题之内存分配
查看>>
水果忍者(切西瓜)
查看>>
集合问题
查看>>
HTML
查看>>
渗透测试辅助工具--在线版
查看>>
Python(Handwriting)
查看>>
09-C语言选择结构(二)
查看>>
虚拟机类加载机制
查看>>
C++0X 学习之 auto
查看>>
火焰图&perf命令
查看>>
可乐鸡翅
查看>>
Spring MVC【入门】就这一篇!
查看>>
windows7 professional.iso
查看>>