Skip to main content

--description--

We know how to search a binary search tree for a specific value. But what if we just want to explore the entire tree? Or what if we don't have an ordered tree and we need to just search for a value? Here we will introduce some tree traversal methods which can be used to explore tree data structures. First up is depth-first search. In depth-first search, a given subtree is explored as deeply as possible before the search continues on to another subtree. There are three ways this can be done: In-order: Begin the search at the left-most node and end at the right-most node. Pre-order: Explore all the roots before the leaves. Post-order: Explore all the leaves before the roots. As you may guess, you may choose different search methods depending on what type of data your tree is storing and what you are looking for. For a binary search tree, an inorder traversal returns the nodes in sorted order.

--instructions--

Here we will create these three search methods on our binary search tree. Depth-first search is an inherently recursive operation which continues to explore further subtrees so long as child nodes are present. Once you understand this basic concept, you can simply rearrange the order in which you explore the nodes and subtrees to produce any of the three searches above. For example, in post-order search we would want to recurse all the way to a leaf node before we begin to return any of the nodes themselves, whereas in pre-order search we would want to return the nodes first, and then continue recursing down the tree. Define inorder, preorder, and postorder methods on our tree. Each of these methods should return an array of items which represent the tree traversal. Be sure to return the integer values at each node in the array, not the nodes themselves. Finally, return null if the tree is empty.

--hints--

The BinarySearchTree data structure should exist.

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

The binary search tree should have a method called inorder.

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

The binary search tree should have a method called preorder.

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

The binary search tree should have a method called postorder.

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

The inorder method should return an array of the node values that result from an inorder traversal.

assert(
(function () {
var test = false;
if (typeof BinarySearchTree !== 'undefined') {
test = new BinarySearchTree();
} else {
return false;
}
if (typeof test.inorder !== 'function') {
return false;
}
test.add(7);
test.add(1);
test.add(9);
test.add(0);
test.add(3);
test.add(8);
test.add(10);
test.add(2);
test.add(5);
test.add(4);
test.add(6);
return test.inorder().join('') == '012345678910';
})()
);

The preorder method should return an array of the node values that result from a preorder traversal.

assert(
(function () {
var test = false;
if (typeof BinarySearchTree !== 'undefined') {
test = new BinarySearchTree();
} else {
return false;
}
if (typeof test.preorder !== 'function') {
return false;
}
test.add(7);
test.add(1);
test.add(9);
test.add(0);
test.add(3);
test.add(8);
test.add(10);
test.add(2);
test.add(5);
test.add(4);
test.add(6);
return test.preorder().join('') == '710325469810';
})()
);

The postorder method should return an array of the node values that result from a postorder traversal.

assert(
(function () {
var test = false;
if (typeof BinarySearchTree !== 'undefined') {
test = new BinarySearchTree();
} else {
return false;
}
if (typeof test.postorder !== 'function') {
return false;
}
test.add(7);
test.add(1);
test.add(9);
test.add(0);
test.add(3);
test.add(8);
test.add(10);
test.add(2);
test.add(5);
test.add(4);
test.add(6);
return test.postorder().join('') == '024653181097';
})()
);

The inorder method should return null for an empty tree.

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

The preorder method should return null for an empty tree.

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

The postorder method should return null for an empty tree.

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

--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;
this.result = [];

this.inorder = function(node) {
if (!node) node = this.root;
if (!node) return null;

if (node.left) this.inorder(node.left);
this.result.push(node.value);
if (node.right) this.inorder(node.right);
return this.result;
};
this.preorder = function(node) {
if (!node) node = this.root;
if (!node) return null;

this.result.push(node.value);
if (node.left) this.preorder(node.left);
if (node.right) this.preorder(node.right);
return this.result;
};
this.postorder = function(node) {
if (!node) node = this.root;
if (!node) return null;

if (node.left) this.postorder(node.left);
if (node.right) this.postorder(node.right);
this.result.push(node.value);

return this.result;
};
}