freeCodeCamp/curriculum/challenges/portuguese/10-coding-interview-prep/data-structures/find-the-minimum-and-maximu...

9.0 KiB

id title challengeType forumTopicId dashedName
587d8257367417b2b2512c7d Encontrar a altura mínima e a máxima de uma árvore binária de busca 1 301641 find-the-minimum-and-maximum-height-of-a-binary-search-tree

--description--

No último desafio, descrevemos um cenário em que uma árvore poderia se tornar desbalanceada. Para entender o conceito de balanço, vamos dar uma olhada em outra propriedade da árvore: altura. A altura de uma árvore representa a distância do nó raiz para qualquer nó de folha dado. Caminhos diferentes em uma estrutura de árvore altamente ramificada podem ter alturas diferentes, mas, para uma determinada árvore, haverá uma altura mínima e máxima. Se a árvore estiver balanceada, estes valores terão uma diferença de, no máximo, um. Isto significa que, em uma árvore equilibrada, todos os nós de folhas existem no mesmo nível. Se não se situarem no mesmo nível, estarão, no máximo, a um nível de distância.

A propriedade de balanço é importante para as árvores, pois é isso que determina a eficiência das operações em uma delas. Como explicamos no último desafio, enfrentamos a pior das hipóteses de complexidade para árvores muito desbalanceadas. As árvores de autobalanceáveis são habitualmente utilizadas para dar conta desta questão nas árvores com conjuntos de dados dinâmicos. Exemplos comuns destas árvores incluem árvores AVL, árvores red-black e árvores B (B-trees). Todas estas árvores contêm uma lógica interna adicional que rebalanceia a árvore quando inserções ou exclusões criam um estado de desbalanceamento.

Observação: uma propriedade similar à altura é a profundidade, que se refere à distância de um determinado nó do nó raiz.

--instructions--

Escreva dois métodos para a nossa árvore binária: findMinHeight e findMaxHeight. Esses métodos devem retornar um valor inteiro para as alturas mínima e máxima dentro de uma determinada árvore binária, respectivamente. Se o nó estiver vazio, vamos atribuir uma altura de -1 (esse é o caso base). Por fim, vamos adicionar um terceiro método isBalanced, que retorna true ou false, dependendo de a árvore estar balanceada ou não. Você pode usar os dois primeiros métodos que acabou de escrever para determinar isso.

--hints--

A estrutura de dados BinarySearchTree deve existir.

assert(
  (function () {
    var test = false;
    if (typeof BinarySearchTree !== 'undefined') {
      test = new BinarySearchTree();
    }
    return typeof test == 'object';
  })()
);

A árvore binária de busca deve ter um método chamado findMinHeight.

assert(
  (function () {
    var test = false;
    if (typeof BinarySearchTree !== 'undefined') {
      test = new BinarySearchTree();
    } else {
      return false;
    }
    return typeof test.findMinHeight == 'function';
  })()
);

A árvore binária de busca deve ter um método chamado findMaxHeight.

assert(
  (function () {
    var test = false;
    if (typeof BinarySearchTree !== 'undefined') {
      test = new BinarySearchTree();
    } else {
      return false;
    }
    return typeof test.findMaxHeight == 'function';
  })()
);

A árvore binária de busca deve ter um método chamado isBalanced.

assert(
  (function () {
    var test = false;
    if (typeof BinarySearchTree !== 'undefined') {
      test = new BinarySearchTree();
    } else {
      return false;
    }
    return typeof test.isBalanced == 'function';
  })()
);

O método findMinHeight deve retornar a altura mínima da árvore.

assert(
  (function () {
    var test = false;
    if (typeof BinarySearchTree !== 'undefined') {
      test = new BinarySearchTree();
    } else {
      return false;
    }
    if (typeof test.findMinHeight !== 'function') {
      return false;
    }
    test.add(4);
    test.add(1);
    test.add(7);
    test.add(87);
    test.add(34);
    test.add(45);
    test.add(73);
    test.add(8);
    return test.findMinHeight() == 1;
  })()
);

O método findMaxHeight deve retornar a altura máxima da árvore.

assert(
  (function () {
    var test = false;
    if (typeof BinarySearchTree !== 'undefined') {
      test = new BinarySearchTree();
    } else {
      return false;
    }
    if (typeof test.findMaxHeight !== 'function') {
      return false;
    }
    test.add(4);
    test.add(1);
    test.add(7);
    test.add(87);
    test.add(34);
    test.add(45);
    test.add(73);
    test.add(8);
    return test.findMaxHeight() == 5;
  })()
);

Uma árvore vazia deve retornar a altura de -1.

assert(
  (function () {
    var test = false;
    if (typeof BinarySearchTree !== 'undefined') {
      test = new BinarySearchTree();
    } else {
      return false;
    }
    if (typeof test.findMaxHeight !== 'function') {
      return false;
    }
    return test.findMaxHeight() == -1;
  })()
);

O método isBalanced deve retornar false se a árvore é uma árvore binária de busca desbalanceada.

assert(
  (function () {
    var test = false;
    if (typeof BinarySearchTree !== 'undefined') {
      test = new BinarySearchTree();
    } else {
      return false;
    }
    if (typeof test.isBalanced !== 'function') {
      return false;
    }
    test.add(4);
    test.add(1);
    test.add(7);
    test.add(87);
    test.add(34);
    test.add(45);
    test.add(73);
    test.add(8);
    return test.isBalanced() === false;
  })()
);

O método isBalanced deve retornar true se a árvore é uma árvore binária de busca balanceada.

assert(
  (function () {
    var test = false;
    if (typeof BinarySearchTree !== 'undefined') {
      test = new BinarySearchTree();
    } else {
      return false;
    }
    if (typeof test.isBalanced !== 'function') {
      return false;
    }
    test.add(10);
    test.add(3);
    test.add(22);
    test.add(1);
    test.add(4);
    test.add(17);
    test.add(32);
    return test.isBalanced() === true;
  })()
);

--seed--

--after-user-code--

BinarySearchTree.prototype = Object.assign(
  BinarySearchTree.prototype,
  {
    add: function(value) {
      function searchTree(node) {
        if (value < node.value) {
          if (node.left == null) {
            node.left = new Node(value);
            return;
          } else if (node.left != null) {
            return searchTree(node.left);
          }
        } else if (value > node.value) {
          if (node.right == null) {
            node.right = new Node(value);
            return;
          } else if (node.right != null) {
            return searchTree(node.right);
          }
        } else {
          return null;
        }
      }

      var node = this.root;
      if (node == null) {
        this.root = new Node(value);
        return;
      } else {
        return searchTree(node);
      }
    }
  }
);

--seed-contents--

var displayTree = tree => console.log(JSON.stringify(tree, null, 2));
function Node(value) {
  this.value = value;
  this.left = null;
  this.right = null;
}
function BinarySearchTree() {
  this.root = null;
  // Only change code below this line

  // Only change code above this line
}

--solutions--

var displayTree = tree => console.log(JSON.stringify(tree, null, 2));
function Node(value) {
  this.value = value;
  this.left = null;
  this.right = null;
}
function BinarySearchTree() {
  this.root = null;
  // Only change code below this line

  // Only change code above this line
  this.findMinHeight = function(root = this.root) {
    // empty tree.
    if (root === null) {
      return -1;
    }
    // leaf node.
    if (root.left === null && root.right === null) {
      return 0;
    }
    if (root.left === null) {
      return this.findMinHeight(root.right) + 1;
    }
    if (root.right === null) {
      return this.findMinHeight(root.left) + 1;
    }
    const lHeight = this.findMinHeight(root.left);
    const rHeight = this.findMinHeight(root.right);
    return Math.min(lHeight, rHeight) + 1;
  };
  this.findMaxHeight = function(root = this.root) {
    // empty tree.
    if (root === null) {
      return -1;
    }
    // leaf node.
    if (root.left === null && root.right === null) {
      return 0;
    }
    if (root.left === null) {
      return this.findMaxHeight(root.right) + 1;
    }
    if (root.right === null) {
      return this.findMaxHeight(root.left) + 1;
    }
    const lHeight = this.findMaxHeight(root.left);
    const rHeight = this.findMaxHeight(root.right);
    return Math.max(lHeight, rHeight) + 1;
  };
  this.isBalanced = function(root = this.root) {
    if (root === null) {
      return true;
    }

    if (root.left === null && root.right === null) {
      return true;
    }

    if (root.left === null) {
      return this.findMaxHeight(root.right) <= 0;
    }

    if (root.right === null) {
      return this.findMaxHeight(root.left) <= 0;
    }

    const lHeight = this.findMaxHeight(root.left);
    const rHeight = this.findMaxHeight(root.right);
    if (Math.abs(lHeight - rHeight) > 1) {
      return false;
    }
    return this.isBalanced(root.left) && this.isBalanced(root.right);
  };
}