Estructura de datos JavaScript de Angry Liver - Colas de dos extremos

¡Acostúmbrate a escribir juntos! Este es el octavo día de mi participación en el "Nuggets Daily New Plan · April Update Challenge", haz clic para ver los detalles del evento .

Hola a todos, mi nombre es Yang Chenggong.

En el último artículo aprendimos sobre una nueva estructura de datos: una cola. Todos también deben comprender el principio de "primero en entrar, primero en salir " en la cola . En este artículo, aprenderemos sobre un tipo especial de cola, llamada cola de dos extremos.

Si aún no sabe qué es una cola, lea el artículo anterior, Estructuras de datos JavaScript de Angry Lives - Colas .

¿Qué es una cola de dos extremos?

Primero observe el concepto de una cola: una cola es un conjunto de colecciones ordenadas que siguen el principio de primero en entrar, primero en salir ( FIFO ). La regla de la cola es agregar nuevos elementos en la cola y eliminar el elemento más cercano de la cabeza.

También dimos un ejemplo de hacer cola. Por ejemplo, si va a comprar el desayuno y ve a alguien al frente, debe hacer cola desde atrás, y la persona al frente comprará el desayuno primero, y luego la siguiente persona puede girar.

Pero piénsalo, habrá tal escenario:

  1. Estaba al final de la fila y de repente hubo una emergencia, así que tuve que irme rápidamente.
  2. Me fui después de pagar y de repente me di cuenta de que no tenía una pajilla, así que corrí al frente a buscar una.

Desde la perspectiva de la cola, estas dos situaciones violan el principio de " primero en entrar, primero en salir ", porque el nuevo elemento que se puso en cola en último lugar se sacó de la cola desde el final de la cola; el primer elemento que debería haber sido sacado de la cola fue en realidad eliminado de la cola. ¡Encolado desde el principio de la cola! Esto es equivalente a la situación de "último en entrar, primero en salir" de la pila en la cola.

De hecho, esta es la cola de dos extremos, y la cola de dos extremos es aproximadamente igual a la cola + pila .

Ahora veamos el concepto específico: la cola de dos extremos , nombre en inglés deque , es una cola especial que nos permite agregar y eliminar elementos de la cabeza y la cola al mismo tiempo. Piense en ello como una estructura de datos que combina una cola y una pila.

La aplicación más común de deques en el mundo de la informática es deshacer . Por ejemplo, si está editando texto, cada operación se registra en un deque. En circunstancias normales, el texto que escriba se insertará continuamente desde el final de esta cola. Cuando se cumplen ciertas condiciones, como un máximo de 1000 palabras, puede eliminar el primer texto del principio de la cola.

Pero de repente descubre que una palabra está mal escrita. En este momento, puede usar ctrl+zdeshacer Esta operación de deshacer es quitar la última palabra del final de la cola, lo que indica que la palabra ha sido eliminada.

Tanto las computadoras como los deques de la vida real siguen los principios de "primero en entrar, primero en salir" y "último en entrar, primero en salir".

Implementación de una cola de dos extremos

Combinando el conocimiento previo, implementamos una cola de dos extremos basada en objetos de JavaScript.

const Deque = (()=> {
  let _start;
  let _end;
  let _items;
  class Deque {
    constructor() {
      _start = 0;
      _end = 0;  
      _items = 0;
    }
  }
  return Deque
})()
复制代码

Como en el código anterior, el itemsatributo se usa para almacenar los elementos de la cola doble, que es exactamente igual que la cola anterior.

Debido a que la cola doble también es una cola, los métodos básicos de la cola, como isEmpty, cleary son exactamente los mismos que los descritos en la size cola anterior, por lo que no entraré en detalles. toStringPara aquellos que necesitan saber, pueden hacer clic en el enlace al principio del artículo.

En comparación con las colas ordinarias, las colas de dos extremos tienen los siguientes métodos:

  • addFront(): añadir un elemento de la cabeza de la deque
  • addBack(): agregue elementos desde el final de la deque (igual que el método de puesta en cola de la cola)
  • removeFront(): elimina un elemento de la cabeza de la deque (igual que el método de dequeue de la cola)
  • removeBack(): elimina un elemento del final de la deque (igual que el método pop de la pila)
  • peekFront(): Devuelve el primer elemento del deque (igual que el método peek de la cola)
  • peekBack(): Devuelve el último elemento de la deque (igual que el método peek de la pila)

Solo estos métodos addFront()son exclusivos de deques, se pueden encontrar otros métodos en las implementaciones de pila y cola. Entonces, veamos cómo se implementa este método único:

addFront(item) {
  if(this.isEmpty()) {
    return this.addBack(item)
  }
  if(_start>0) {
    _start--;
    _items[_start] = item
  } else {
    for(let i = 0; i<_end; i++) {
      _items[i+1] = _items[i]
    }
    _end++;
    _start = 0;
    _items[0] = item
  }
}
复制代码

El código anterior implementa la cola al principio de la cola doble, que se divide en tres casos.

Caso 1: La cola está vacía

Si la cola está vacía, insertar elementos de la cabeza y la cola de la cola es lo mismo. Entonces, en este caso, podemos llamar directamente al método de inserción de elementos desde el final.

Caso 2: El valor de inicio es mayor que 0

Un valor de start mayor que 0 significa que el deque ya ha sido dequeued, en este caso, solo necesitamos poner el elemento recién agregado en la posición del último elemento dequeued. El valor clave de esta posición es el tiempo start - 1.

Caso 3: El valor de inicio es igual a 0

Un valor de start igual a 0 significa que no hay elementos en la deque. En este momento, para agregar un nuevo elemento al encabezado, mueva el valor clave de todos los elementos en la cola un bit hacia atrás, es decir, +1. Deje que el valor clave del nuevo elemento sea 0.

Se han introducido otros métodos en el artículo pila y cola.El código completo es el siguiente:

const Deque = (() => {
  let _start
  let _end
  let _items
  class Deque {
    constructor() {
      _start = 0
      _end = 0
      _items = 0
    }
    // 头部入列
    addFront(item) {
      if (this.isEmpty()) {
        return this.addBack(item)
      }
      if (_start > 0) {
        _start--
        _items[_start] = item
      } else {
        for (let i = 0; i < _end; i++) {
          _items[i + 1] = _items[i]
        }
        _end++
        _start = 0
        _items[0] = item
      }
    }
    // 尾部入列
    addBack(item) {
      _items[_end] = item
      _end++;
    }
    // 头部出列
    removeFront() {
      if (this.isEmpty()) {
        return undefind
      }
      let item = _items[_start]
      delete _items[_start]
      _start++;
      return item
    }
    // 尾部出列
    removeBack() {
      if (this.isEmpty()) {
        return undefined
      }
      _end--;
      let item = _items[_end]
      delete _items[_end]
      return item
    }
    // 头部第一个元素
    peekFront() {
      if (this.isEmpty()) {
        return undefined
      }
      return _items[_start]
    }
    // 尾部第一个元素
    peekBack() {
      if (this.isEmpty()) {
        return undefined
      }
      return _items[_end]
    }
    size() {
      return _end - _start
    }
    isEmpty() {
      return _end - _start === 0
    }
    clear() {
      _items = {}
      _start = 0
      _end = 0
    }
    toString() {
      let arr = Object.values(_items)
      return arr.toString()
    }
  }
  return Deque
})()
复制代码

usar deque

El código completo anterior es relativamente largo, probémoslo primero:

// 实例化
var deque = new Deque();
console.log(deque.isEmpty()); // true
复制代码

Primero pruebe el resultado de poner en cola la cabeza:

deque.addFront("北京");
deque.addFront("上海");
console.log(deque.size()); // 2
console.log(deque.toString()); // 上海,北京
复制代码

No hay problema con ver el resultado de la impresión, intentemos ingresar la columna al final nuevamente:

deque.addBack("杭州");
deque.addBack("南京");
console.log(deque.size()); // 4
console.log(deque.toString()); // 上海,北京,杭州,南京
复制代码

La entrada de la cola también es la esperada, y finalmente mire la salida de la cola:

// 头部出列
console.log(deque.removeFront()); // 上海
// 尾部出列
console.log(deque.removeBack()); // 南京
console.log(deque.size()); // 2
console.log(deque.toString()); // 北京,杭州
复制代码

Mmmm, todo está hecho a la perfección.

Resumir

Este artículo presenta el concepto de colas de dos extremos e implementa manualmente una cola de dos extremos. No sé si ya lo has aprendido. Si encuentra algunos métodos que no comprende, haga clic en la columna para ver los artículos anteriores de la serie de estructuras de datos.

La fuente de este artículo es la cuenta oficial: Programmer Success . Esta es la séptima parte del aprendizaje de estructuras de datos y algoritmos de JavaScript. Esta serie se actualizará durante un mes. Bienvenido a prestar atención a la cuenta oficial y haga clic en " Agregar grupo " para unirse a nuestro equipo de aprendizaje ~

Supongo que te gusta

Origin juejin.im/post/7084261922576531469
Recomendado
Clasificación