freeCodeCamp/curriculum/challenges/portuguese/10-coding-interview-prep/data-structures/create-a-circular-queue.md

5.8 KiB

id title challengeType forumTopicId dashedName
587d8255367417b2b2512c75 Criar uma fila circular 1 301625 create-a-circular-queue

--description--

Neste desafio, você criará uma fila circular. Uma fila circular é uma fila escreve até o final de uma coleção e que, então, começa a se sobrescrever no início da coleção. Este tipo de estrutura de dados é útil em certas situações. Por exemplo, uma fila circular pode ser usada para streaming de mídia. Quando a fila está cheia, os novos dados de mídia vão sobrescrever os dados antigos.

Uma boa maneira de ilustrar esse conceito é com um array de tamanho 5:

[null, null, null, null, null]
 ^Read @ 0
 ^Write @ 0

Aqui, a leitura e a escrita estão ambos na posição 0. Agora, a fila recebe 3 novos registros a, b, e c. Nossa fila agora se parece assim:

[a, b, c, null, null]
 ^Read @ 0
          ^Write @ 3

Como a cabeça de leitura lê, pode remover valores ou mantê-los:

[null, null, null, null, null]
                   ^Read @ 3
                   ^Write @ 3

Agora, gravamos os valores d, e e f na fila. Quando a gravação atinge o fim do array, ela retorna ao início:

[f, null, null, d, e]
                ^Read @ 3
    ^Write @ 1

Esta abordagem requer uma quantidade constante de memória, mas permite que arquivos de um tamanho muito maior sejam processados.

--instructions--

Neste desafio, você criará uma fila circular. A fila circular deve fornecer os métodos enqueue e dequeue, que permitem que você leia e grave na fila. A classe também deve aceitar um argumento inteiro que você pode usar para especificar o tamanho da fila quando criada. Gravamos a versão inicial desta classe para você no editor de código.

Quando você incluir itens na fila, o ponteiro de gravação deve avançar para frente e retornar para o início assim que chegar ao final da fila. O método enqueue deve retornar o item que você colocou na fila se for bem-sucedido. Caso contrário, ele retornará null.

Da mesma forma, o ponteiro de leitura deve avançar enquanto você remove os itens da fila. Quando você remove um item, o item deve ser retornado. Se você não puder remover um item da fila, você deve retornar null.

Não deve ser permitido ao ponteiro de gravação passar pelo ponteiro de leitura (nossa classe não permitirá que você substitua dados que ainda não leu). Além disso, o ponteiro de leitura não deve ser capaz de avançar passando por dados que você gravou.

--hints--

O método enqueue deve adicionar itens à fila circular.

assert(
  (function () {
    var test = new CircularQueue(3);
    test.enqueue(17);
    test.enqueue(32);
    test.enqueue(591);
    var print = test.print();
    return print[0] === 17 && print[1] === 32 && print[2] === 591;
  })()
);

Você não deve enfileirar itens além do ponteiro de leitura.

assert(
  (function () {
    var test = new CircularQueue(3);
    test.enqueue(17);
    test.enqueue(32);
    test.enqueue(591);
    test.enqueue(13);
    test.enqueue(25);
    test.enqueue(59);
    var print = test.print();
    return print[0] === 17 && print[1] === 32 && print[2] === 591;
  })()
);

O método dequeue deve remover os itens da fila.

assert(
  (function () {
    var test = new CircularQueue(3);
    test.enqueue(17);
    test.enqueue(32);
    test.enqueue(591);
    return (
      test.dequeue() === 17 && test.dequeue() === 32 && test.dequeue() === 591
    );
  })()
);

Depois que um item for removido da fila, sua posição na fila deve ser redefinida para null.

assert(
  (function () {
    var test = new CircularQueue(3);
    test.enqueue(17);
    test.enqueue(32);
    test.enqueue(672);
    test.dequeue();
    test.dequeue();
    var print = test.print();
    return print[0] === null && print[1] === null && print[2] === 672;
  })()
);

Tentando remover da fila além do ponteiro de gravação deve retornar null e não avançará esse ponteiro.

assert(
  (function () {
    var test = new CircularQueue(3);
    test.enqueue(17);
    test.enqueue(32);
    test.enqueue(591);
    return (
      test.dequeue() === 17 &&
      test.dequeue() === 32 &&
      test.dequeue() === 591 &&
      test.dequeue() === null &&
      test.dequeue() === null &&
      test.dequeue() === null &&
      test.dequeue() === null &&
      test.enqueue(100) === 100 &&
      test.dequeue() === 100
    );
  })()
);

--seed--

--seed-contents--

class CircularQueue {
  constructor(size) {

    this.queue = [];
    this.read = 0;
    this.write = 0;
    this.max = size - 1;

    while (size > 0) {
      this.queue.push(null);
      size--;
    }
  }

  print() {
    return this.queue;
  }

  enqueue(item) {
    // Only change code below this line

    // Only change code above this line
  }

  dequeue() {
    // Only change code below this line

    // Only change code above this line
  }
}

--solutions--

class CircularQueue {
  constructor(size) {
    this.queue = [];
    this.read = 0;
    this.write = 0;
    this.max = size - 1;

    while (size > 0) {
      this.queue.push(null);
      size--;
    }
  }

  print() {
    return this.queue;
  }

  enqueue(item) {
    // Only change code below this line
    console.log(this.write, this.max);
    if (this.queue[this.write] === null) {
      this.queue[this.write++] = item;

      if (this.write > this.max) {
        this.write = 0;
      }
      return item;
    }
    return null;
    // Only change code above this line
  }

  dequeue() {
    // Only change code below this line
    if (this.queue[this.read] !== null) {
      let item = this.queue[this.read];
      this.queue[this.read++] = null;
      if (this.read > this.max) {
        this.read = 0;
      }
      return item;
    }
    return null;
    // Only change code above this line
  }
}