Thursday, December 8, 2022

### JavaScript (NodeJS) Recursive Function

A recursive function in JavaScript or Node.js is a function that calls itself until a certain condition is met. This allows the function to perform a repetitive task, such as iterating over a list of elements or traversing a tree-like data structure, in a compact and elegant manner.

Here is an example of a recursive function that calculates the factorial of a given number:

``````
function factorial(n) {
// If n is 0 or 1, return 1
if (n === 0 || n === 1) {
return 1;
}

// Recursively call the function with n - 1
// and multiply the result by n
return factorial(n - 1) * n;
}

// Calculate the factorial of 5
let result = factorial(5);
console.log(result); // Output: 120
```
```

In the above example, the `factorial` function calculates the factorial of a given number by calling itself with `n - 1` until `n` is 0 or 1, at which point the function returns 1. The result of each recursive call is then multiplied by `n` to compute the final result.

Recursive functions are commonly used in algorithms and data structures, such as sorting and searching algorithms, and tree traversal algorithms. They can also be used to solve complex problems that can be divided into smaller, simpler sub-problems, such as mathematical or computational puzzles.

Here is another example of a recursive function in Node.js that calculates the sum of all elements in an array:

``````
function sum(arr) {
// If the array is empty, return 0
if (arr.length === 0) {
return 0;
}

// Recursively call the function with the array without the first element
// and add the first element to the result
return sum(arr.slice(1)) + arr[0];
}

// Calculate the sum of the array [1, 2, 3, 4, 5]
let result = sum([1, 2, 3, 4, 5]);
console.log(result); // Output: 15
```
```

In the above example, the `sum` function calculates the sum of all elements in an array by calling itself with the array without the first element until the array is empty, at which point the function returns 0. The result of each recursive call is then added to the first element of the array to compute the final result.

This recursive function can be used to compute the sum of any array of numbers, regardless of its size or complexity. It can also be easily modified to perform other operations, such as computing the average, the minimum, or the maximum of the array elements.

### Class and Methods recursion in NodeJS

Here is an example of a recursive function that is defined as a method of a class in Node.js:

``````
class Tree {
constructor(value) {
this.value = value;
this.children = [];
}

// Add a child node to the tree
addChild(value) {
let child = new Tree(value);
this.children.push(child);
return child;
}

// Recursively traverse the tree and print the value of each node
traverse() {
// Print the value of the current node
console.log(this.value);

// Recursively call the function for each child node
this.children.forEach((child) => child.traverse());
}
}

// Create a tree with the root node having the value "Root"
let tree = new Tree("Root");

// Add some child nodes to the tree
let child1 = tree.addChild("Child 1");
let child2 = tree.addChild("Child 2");
let child3 = tree.addChild("Child 3");

// Add some grandchild nodes to the tree
child1.addChild("Grandchild 1");
child1.addChild("Grandchild 2");
child2.addChild("Grandchild 3");
child3.addChild("Grandchild 4");

// Traverse the tree and print the value of each node
tree.traverse();
// Output:
// Root
// Child 1
// Grandchild 1
// Grandchild 2
// Child 2
// Grandchild 3
// Child 3
// Grandchild 4
```
```

In the above example, the Tree class defines a tree-like data structure with a root node and child nodes. The addChild method adds a child node to the tree, and the traverse method recursively traverses the tree and prints the value of each node.

The traverse method uses a recursive function to traverse the tree, starting from the root node and calling itself for each child node until it reaches the leaf nodes, which have no children. This allows the method to efficiently traverse the tree and perform the desired operation on each node.

Recursive functions can be easily defined as methods of a class, just like any other method. This allows the recursive function to access the properties and methods of the class, and use them to solve the problem or perform the desired operation.

In the above example, the `traverse` method uses the `value` property of the Tree class to print the value of each node, and the `children` property to call the method recursively for each child node. This allows the method to traverse the tree and print the value of each node without the need to explicitly pass the tree or the node to the function.

Recursive functions defined as methods of a class can also be easily extended or overridden, depending on the specific needs of the problem or the desired operation. For example, we can define a new class that extends the `Tree` class and overrides the `traverse` method to perform a different operation on the tree nodes, such as calculating the sum of the node values or printing the height of the tree.

``````
class SumTree extends Tree {
// Override the traverse method to calculate the sum of all node values
traverse() {
// Initialize the sum to the value of the current node
let sum = this.value;

// Recursively call the function for each child node
// and add the result to the sum
this.children.forEach((child) => {
sum += child.traverse();
});

// Return the sum
return sum;
}
}

// Create a SumTree with the root node having the value 5
let sumTree = new SumTree(5);

// Add some child nodes to the tree
sumTree.addChild(10);
sumTree.addChild(20);
sumTree.addChild(30);

// Traverse the tree and calculate the sum of all node values
let result = sumTree.traverse();
console.log(result); // Output: 65
```
```

In the above example, the `SumTree` class extends the `Tree` class and overrides the `traverse` method to calculate the sum of all node values instead of printing them. This allows the method to efficiently traverse the tree and compute the sum without the need to explicitly pass the tree or the node to the function.