一种用于二叉树搜索,遍历,插入和删除的算法

时间:2019-02-14 05:39:02

标签: javascript algorithm binary-tree

我看到像this这样的二叉树实现:

var insert = function(value, root) {
  if (!root) {
    // Create a new root.
    root = { val: value };
  }
  else {
    var current = root;
    while (current) {
      if (value < current.val) {
        if (!current.left) {
          // Insert left child.
          current.left = { val: value };
          break;
        }
        else {
          current = current.left;
        }
      }
      else if (value > current.val) {
        if (!current.right) {
          // Insert right child.
          current.right = { val: value };
          break;
        }
        else {
          current = current.right;
        }
      }
      else {
        // This value already exists. Ignore it.
        break;
      }
    }
  }

  return root;
}

var exists = function(value, root) {
  var result = false;

  var current = root;
  while (current) {
    if (value < current.val) {
      current = current.left;
    }
    else if (value > current.val) {
      current = current.right;
    }
    else {
      result = true;
      break;
    }
  }

  return result;
}

var traversePre = function(head, callback) {
  // Preorder traversal.
  if (head) {
    if (callback) {
      callback(head.val);
    }

    traversePre(head.left, callback);
    traversePre(head.right, callback);
  }
}

var traversePost = function(head, callback) {
  // Postorder traversal.
  if (head) {
    traversePost(head.left, callback);
    traversePost(head.right, callback);

    if (callback) {
      callback(head.val);
    }
  }
}

var traverseIn = function(head, callback) {
  // Inorder traversal.
  if (head) {
    traverseIn(head.left, callback);

    if (callback) {
      callback(head.val);
    }

    traverseIn(head.right, callback);
  }  
}

var traverseInIterative = function(head, callback) {
  // Inorder traversal (iterative style).
  var current = head;
  var history = [];

  // Move down to the left-most smallest value, saving all nodes on the way.
  while (current) {
    history.push(current);
    current = current.left;
  }

  current = history.pop();
  while (current) {
    if (callback) {
      callback(current.val);
    }

    // Move to the right, and then go down to the left-most smallest value again.
    current = current.right;
    while (current) {
      history.push(current);
      current = current.left;
    }

    current = history.pop();
  }
}

var root = insert(10);
insert(5, root);
insert(6, root);
insert(3, root);
insert(20, root);

特别是traverseInIterative对我来说看起来不错。但是我想知道是否真的需要insertexists,是否同样需要searchdelete。我发现(就像在这些实现中一样)它们的实现方式有所不同,但是我想知道是否可以实现一个通用的匹配功能,一次解决所有性能,同时在性能方面达到理想。

1 个答案:

答案 0 :(得分:0)

一种设计通用方法以执行所有操作的方法是-

genericMethod(value, root, command)

此处的command参数将接收一个字符串,该字符串指定insertdeletesearch。根据命令参数,您可以调整内部实现以支持所有操作。

现在让我们来谈谈性能和设计角度的问题。我认为使用这种方法并不理想。拥有这样的通用方法会给您带来比您想象的更多的问题。

现在,在检查代码之后-有很多可以改进的地方,根据我的看法,它们将为您带来更好的体验-

  • 对于插入/删除-您需要检查该值是否已经存在。因此,只需调用exists()方法,而不是在那些方法中编写相同的代码即可。

这种类型的通用行为可确保您不会一次又一次地编写相同的代码,也不会重复编写SRP(单一职责原理),因此您的代码是完全分隔开的,并且更易于阅读。