JS数据结构和算法1

121 阅读2分钟

数据结构和算法

什么是数据结构

  • 在计算机中,存储和组织数据的方式
  • 例如:图书馆图书摆放、快递摆放

什么是算法

  • 解决问题的方法和步骤
  • 通常用来更加高效的获取数据和处理数据

数组

  • 数组是线性结构
  • 可以在数组的任意位置插入和删除元素
  • 在数组的开头或中间位置,插入和删除元素效率低,需要位移其他元素
  • 数组的查找和修改元素效率非常高

栈 Stack,后进先出(LIFO)

  • 栈(stack)是一种受限的线性结构,仅允许在表的一端进行插入和删除运算。
  • 可操作的一端:栈顶; 不可操作的一端:栈底
  • LIFO:Last In First Out , 最后一个进,第一个出
  • 相当于有底的存储桶:例如,叠盘子、储物箱,就是先放的就在底部,后放的在上面,后进先出
  • 添加:进栈
  • 删除:出栈
  • 特点:后进先出
  1. 程序中的栈的应用
  • 函数调用栈:A函数 调用 B函数, B函数 又调用 C函数
  • 递归:不断调用自己,会不断压栈,很容易出现栈溢出

image.png

image.png

  1. 栈面试题
  • 答案:C image.png
  1. 栈的封装
  • 栈中常见的操作

image.png

  • 栈的封装
<script>
    // 栈的封装
    function Stack() {
      // 栈中的属性
      this.items = [];

      // 栈的相关操作
      // 1. 进栈
      Stack.prototype.push = function (item) {
        this.items.push(item);
      }
      
      // 2. 从栈中取出元素
      Stack.prototype.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 () {
        // 主要是返回形式
        return this.items.toString();
      }
    }
    
    var s = new Stack();
    s.push(20);
    s.push(30);
    s.push(40);
    console.log('栈顶元素 peek: ', s.peek())
    console.log('取出栈顶元素 pop: ', s.pop())
    console.log('判断栈是否为空 isEmpty: ', s.isEmpty())
    console.log('栈的长度 size: ', s.size())
    console.log('返回栈元素的拼接字符串 toString: ', s.toString())
  </script>

image.png

  1. 十进制转二进制
  • toString() 方法:①转为字符串; ②已十进制为基地,转化为对应的参数进制

image.png

  • parseInt() 方法:①parseInt(a) 将变量转化为整型,从左往右检查,直到非数字字符为止;②直接使用方法,有两个参数,parseInt(a, b),表示 a 已 b 进制为基底,转化为 十进制

image.png

  • 利用封装好的 Stack 栈,实现十进制转二进制操作
<script>
    // 栈的应用:十进制转二进制
    function decTobin (decNumber) {
      // 新建栈
      var stack = new Stack();

      while (decNumber > 0) {
        stack.push(decNumber % 2)
        decNumber = Math.floor(decNumber / 2)
      }
      var binStr = '';
      while (!stack.isEmpty()) {
        binStr += stack.pop()
      }
      console.log(binStr)
    }
</script>

image.png

队列(Queue)

  • 队列:受限的线性结构,先进先出(FIFO, First Int First Out)
  • 只允许在表的前端(first)进行删除操作,表的后端(rear)进行插入操作
  • 例如:排队(不允许插队)
  1. 队列的应用
  • 打印队列:打印机会按先进入的文档先打印,后进入的文档后打印
  • 线程队列:当线程过多时,排队等候执行

image.png

  1. 队列的封装
  • 队列常见操作

image.png

  • 封装队列
<script>
    // 利用数组封装队列
    function Queue() {
      // 属性
      this.items = [];

      // 1. 元素加入队列
      Queue.prototype.enqueue = function (item) {
        this.items.push(item);
      }

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

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

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

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

      // 6. toString方法
      Queue.prototype.toString = function () {
        // 返回怎样类型的字符串自己定义
        return this.items.toString();
      }

    }

    // 使用队列
    var queue = new Queue();

    // 入队
    queue.enqueue('a');
    queue.enqueue('b');
    queue.enqueue('c');
    queue.enqueue('d');
    console.log(queue.toString())
    console.log("查看队列中的个数", queue.size())
    console.log("出队", queue.dequeue())
    console.log("出队后", queue.toString())
  </script>

image.png

  1. 面试题:击鼓传花
  • 规则

image.png

  • 实现
<script>
    // 击鼓传花:利用队列解决问题
    function passGame(nameList, num) {
      // 1. 创建一个队列结构
      var que = new Queue();

      // 2. 将所有人加入到队列中
      for(var i = 0; i < nameList.length; i++) {
        que.enqueue(nameList[i]);
      }

      while (que.size() > 1) {
        // 3. 开始数数,num之前的重新加入队列末尾
        for(var i = 0; i < num - 1; i++){
          que.enqueue(que.dequeue())
        }
        // 数到num的那个人直接删除
        que.dequeue()
      }

      // 4. 获取剩下的那个人
      console.log(que.front())
    }
</script>

image.png

优先级队列

  • 优先级队列,每个元素包含数据和优先级,添加数据会先根据优先级进行比较,然后再插入正确的位置

  • 优先级队列应用

image.png

  • 优先级队列的实现,主要是添加元素的操作,需要根据队列中每个元素的优先级进行比较,然后决定插入的位置
<script>
    // 封装优先级队列
    function PriorityQueue () {

      // 在 PriorityQueue重新创建一个类:内部类
      function QueueElement(element, priority) {
        this.element = element;
        this.priority = priority;
      }

      // 属性
      this.items = [];

      // 1. 插入方法
      PriorityQueue.prototype.enqueue = function (element, priority) {
        // 1. 创建 QueueElement 对象
        var queueElement = new QueueElement(element, priority);

        // 2. 判断队列是否为空
        if (this.items.length === 0) {
          this.items.push(queueElement);
        } else {
          var added = false;
          for (var i = 0; i < this.items.length; i++) {
            if(queueElement.priority < this.items[i].priority) {
              this.items.splice(i, 0, queueElement);
              added = true;
              break;
            }
          }
          if (!added) {
            this.items.push(queueElement);
          }
        }
      }

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

      // 3. 查看前端元素
      PriorityQueue.prototype.front = function () {
        return this.items[0];
      }

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

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

      // 6. toString方法
      PriorityQueue.prototype.toString = function () {
        // 返回怎样类型的字符串自己定义
        // return this.items.toString();
        var str = "";
        this.items.forEach(item => {
          str += `${item.element} `
        })
        console.log(str);
        return str.trim();
      }
    }

    var pq = new PriorityQueue();
    pq.enqueue(12, 3);
    pq.enqueue(13, 2);
    pq.enqueue(14, 1);
    console.log(pq.size())
    console.log(pq.toString())
  </script>

image.png