Skip to main content

Trees

Trees are nodes that are in a parent-child relationship.

  • Root: it is the top node of a tree.
  • Child: it is a node directly connected to another node when moving away from the root.
  • Parent: The converse of a child.
  • Siblings: group nodes with the same parent.
  • Leaf : A node with no children.
  • Edge : The connection between one node and another.

There are types of trees.

Binary Search Tree​

  • Every parent node has at the most two children.
  • Every node to the left of the parent node is always less than the parent.
  • Every node to the right of the parent node is always greater than the parent

Tree Traversal​

These are independent of type of trees and can be applied across. There are two types of traversal.

  • BFS.
  • DFS.

Breadth First Search (BFS)​

BFS is searching across the tree on each level.

Psuedocode BFS​

  • Create a queue and a variable to store the values of nodes visited.
  • Place the root node in the queue.
  • Loop as long as there is anything in the queue.
    • Dequeue a node from the queue and push the value of the node into the variable that stores the nodes
    • If there is a left property on the dequeued node - add it to the queue.
    • if there is a right property on the dequeued node - add it to the queue.
  • Return the variable that is storing values.

Depth First Search (DFS)​

DFS is vertically going down and searching.

  • there are 3 ways of DFS
    • PreOrder: Visit the current node, then left subtree, then right subtree.
    • InOrder: Visit the left subtree, then current node, then right subtree.
    • PostOrder: Visit the left subtree, then right subtree, then current node.

Psuedocode PreOrder DFS​

  • Create a variable to store the values of the node visited.
  • Store the root of the tree in a variable called current.
  • Write a helper function which accepts a node.
    • Push the value of the node to the variable that stores the values.
    • If the node has a left property, call the helper function with the left property on the node.
    • If the node has a right property, call the helper funciton with the right property on the node.
  • Invoke the helper function with the current variable.
  • Return the array of values.

Psuedocode PostOrder DFS​

  • Create a variable to store the values of the node visited.
  • Store the root of the tree in a variable called current.
  • Write a helper function which accepts a node.
    • If the node has a left property, call the helper function with the left property on the node.
    • If the node has a right property, call the helper funciton with the right property on the node.
    • Push the value of the node to the variable that stores the values
    • Invoke the helper function with the current variable.
  • Return the array of values.

Psuedocode InOrder DFS​

  • Create a variable to store the values of the node visited.
  • Store the root of the tree in a variable called current.
  • Write a helper function which accepts a node.
    • If the node has a left property, call the helper function with the left property on the node.
    • Push the value of the node to the variable that stores the values
    • If the node has a right property, call the helper funciton with the right property on the node.
    • Invoke the helper function with the current variable.
  • Return the array of values.

Tree implementation​

class Node {
constructor(value) {
this.value = value;
this.left = null;
this.right = null;
}
}

class BinarySearchTree {
constructor() {
this.root = null;
}
insert(value) {
let newNode = new Node(value);
if (this.root === null) {
this.root = newNode;
return this;
}
let current = this.root;
while (true) {
if (value === current.value) return undefined;
if (value < current.value) {
if (current.left === null) {
current.left = newNode;
return this;
}
current = current.left;
} else {
if (current.right === null) {
current.right = newNode;
return this;
}
current = current.right;
}
}
}
find(value) {
if (this.root === null) return false;
let current = this.root;
let found = false;
while (current && !found) {
if (value < current.value) {
current = current.left;
} else if (value > current.value) {
current = current.right;
} else {
return true;
}
}

return false;
}
BFS() {
let node = this.root;
let data = [];
let queue = [];
queue.push(node);
while (queue.length) {
node = queue.shift();
data.push(node.value);
if (node.left) queue.push(node.left);
if (node.right) queue.push(node.right);
}
return data;
}
DFSPreOrder() {
let data = [];
let current = this.root;
function traverse(node) {
data.push(node.value);
if (node.left) traverse(node.left);
if (node.right) traverse(node.right);
}
traverse(current);

return data;
}
DFSPostOrder() {
let data = [];
let current = this.root;
function traverse(node) {
if (node.left) traverse(node.left);
if (node.right) traverse(node.right);
data.push(node.value);
}
traverse(current);

return data;
}
DFSPostOrder() {
let data = [];
let current = this.root;
function traverse(node) {
if (node.left) traverse(node.left);
data.push(node.value);
if (node.right) traverse(node.right);
}
traverse(current);

return data;
}
}