Skip to content

Commit b6dfa0f

Browse files
committed
chapter 08: [Recursion]
1 parent b337fe8 commit b6dfa0f

22 files changed

+402
-3
lines changed

.eslintrc.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"import/prefer-default-export": 0,
2626
"comma-dangle": 0,
2727
"no-underscore-dangle": 0,
28-
"no-param-reassign": 0
28+
"no-param-reassign": 0,
29+
"no-return-assign": 0
2930
}
3031
}

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Work in Progress.
1717
* 05: [LinkedLists](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter05)
1818
* 06: [Sets](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter06)
1919
* 07: [Dictionaries and Hashes](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter07)
20+
* 08: [Recursion](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter08)
2021

2122
### Third Edition Updates
2223

examples/PacktDataStructuresAlgorithms.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8">
5+
<title></title>
6+
</head>
7+
<body>
8+
<script src="01-IntroRecursion.js"></script>
9+
</body>
10+
</html>
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
2+
// functions commented below - inifite loop
3+
4+
/*
5+
function recursiveFunction(someParam) {
6+
recursiveFunction(someParam);
7+
}
8+
9+
function recursiveFunction1(someParam) {
10+
recursiveFunction2(someParam);
11+
}
12+
13+
function recursiveFunction2(someParam) {
14+
recursiveFunction1(someParam);
15+
}
16+
*/
17+
18+
function understandRecursion(doIunderstandRecursion) {
19+
const recursionAnswer = confirm('Do you understand recursion?'); // function logic
20+
if (recursionAnswer === true) { // base case or stop point
21+
return true;
22+
}
23+
understandRecursion(recursionAnswer); // recursive call
24+
}
25+
26+
understandRecursion(false);

examples/chapter08/02-Factorial.html

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8">
5+
<title></title>
6+
</head>
7+
<body>
8+
<script src="02-Factorial.js"></script>
9+
</body>
10+
</html>

examples/chapter08/02-Factorial.js

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// @ts-check
2+
3+
function factorialIterative(number) {
4+
if (number < 0) {
5+
return undefined;
6+
}
7+
let total = 1;
8+
for (let n = number; n > 1; n--) {
9+
total = total * n;
10+
}
11+
return total;
12+
}
13+
14+
console.log('factorialIterative(5): ', factorialIterative(5));
15+
console.log('factorialIterative(3): ', factorialIterative(3));
16+
17+
function factorial(n) {
18+
// console.trace();
19+
if (n === 1 || n === 0) {
20+
return 1;
21+
}
22+
return n * factorial(n - 1);
23+
}
24+
25+
console.log('factorial(5): ', factorial(5));
26+
console.log('factorial(3): ', factorial(3));
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8">
5+
<title></title>
6+
</head>
7+
<body>
8+
<script src="03-JSCallStack.js"></script>
9+
</body>
10+
</html>

examples/chapter08/03-JSCallStack.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
let i = 0;
2+
function recursiveFn() {
3+
i++;
4+
recursiveFn();
5+
}
6+
7+
try {
8+
recursiveFn();
9+
} catch (ex) {
10+
console.log('i = ' + i + ' error: ' + ex);
11+
}

examples/chapter08/04-Fibonacci.html

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8">
5+
<title></title>
6+
</head>
7+
<body>
8+
<script src="04-Fibonacci.js"></script>
9+
</body>
10+
</html>

examples/chapter08/04-Fibonacci.js

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
function fibonacci(n){
2+
if (n < 1) return 0; // {1}
3+
if (n <= 2) return 1; // {2}
4+
return fibonacci(n - 1) + fibonacci(n - 2); // {3}
5+
}
6+
7+
console.log('fibonacci(2)', fibonacci(2));
8+
console.log('fibonacci(3)', fibonacci(3));
9+
console.log('fibonacci(4)', fibonacci(4));
10+
console.log('fibonacci(5)', fibonacci(5));
11+
12+
function fibonacciIterative(n){
13+
let fibNMinus2 = 0;
14+
let fibNMinus1 = 1;
15+
let fibN = n;
16+
for (let i = 2; i <= n; i++) { // n >= 2
17+
fibN = fibNMinus1 + fibNMinus2; // f(n-1) + f(n-2)
18+
fibNMinus2 = fibNMinus1;
19+
fibNMinus1 = fibN;
20+
}
21+
return fibN;
22+
}
23+
24+
console.log('fibonacciIterative(2)', fibonacciIterative(2));
25+
console.log('fibonacciIterative(3)', fibonacciIterative(3));
26+
console.log('fibonacciIterative(4)', fibonacciIterative(4));
27+
console.log('fibonacciIterative(5)', fibonacciIterative(5));
28+
29+
function fibonacciMemoization(n) {
30+
const memo = [0, 1];
31+
const fibonacci = (n) => {
32+
if (memo[n] != null) return memo[n];
33+
return memo[n] = fibonacci(n - 1, memo) + fibonacci(n - 2, memo);
34+
};
35+
return fibonacci(n);
36+
}
37+
38+
console.log('fibonacciMemoization(2)', fibonacciMemoization(2));
39+
console.log('fibonacciMemoization(3)', fibonacciMemoization(3));
40+
console.log('fibonacciMemoization(4)', fibonacciMemoization(4));
41+
console.log('fibonacciMemoization(5)', fibonacciMemoization(5));
42+
43+
// https://jsperf.com/fibonacci-comparison-jsbook

examples/index.html

+15
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
<a href="#scroll-tab-5" class="mdl-layout__tab">05</a>
4646
<a href="#scroll-tab-6" class="mdl-layout__tab">06</a>
4747
<a href="#scroll-tab-7" class="mdl-layout__tab">07</a>
48+
<a href="#scroll-tab-8" class="mdl-layout__tab">08</a>
4849
</div>
4950
</header>
5051
<main class="mdl-layout__content">
@@ -173,6 +174,20 @@
173174
</div>
174175
</section>
175176
<section class="mdl-layout__tab-panel" id="scroll-tab-8">
177+
<div class="page-content">
178+
<div class="page-content mdl-layout--fixed-drawer">
179+
<div class="mdl-layout__drawer is-visible">
180+
<nav class="mdl-navigation">
181+
<a class="mdl-navigation__link" href="chapter08/01-IntroRecursion.html">01-IntroRecursion</a>
182+
<a class="mdl-navigation__link" href="chapter08/02-Factorial.html">02-Factorial</a>
183+
<a class="mdl-navigation__link" href="chapter08/03-JSCallStack.html">03-JSCallStack</a>
184+
<a class="mdl-navigation__link" href="chapter08/04-Fibonacci.html">04-Fibonacci</a>
185+
</nav>
186+
</div>
187+
</div>
188+
</div>
189+
</section>
190+
<section class="mdl-layout__tab-panel" id="scroll-tab-9">
176191
<div class="page-content">
177192
Soon.
178193
</div>

src/js/index.js

+7
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,10 @@ export { default as HashTable } from './data-structures/hash-table';
3434
export { default as HashTableSeparateChaining } from './data-structures/hash-table-separate-chaining';
3535
export { default as HashTableLinearProbing } from './data-structures/hash-table-linear-probing';
3636
export { default as HashTableLinearProbingLazy } from './data-structures/hash-table-linear-probing-lazy';
37+
38+
// chapter 08
39+
export { default as factorialIterative } from './others/factorial';
40+
export { default as factorial } from './others/factorial';
41+
export { default as fibonacci } from './others/fibonacci';
42+
export { default as fibonacciIterative } from './others/fibonacci';
43+
export { default as fibonacciMemoization } from './others/fibonacci';

src/js/others/factorial.js

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
export function factorialIterative(number) {
2+
if (number < 0) {
3+
return undefined;
4+
}
5+
let total = 1;
6+
for (let n = number; n > 1; n--) {
7+
total *= n;
8+
}
9+
return total;
10+
}
11+
12+
export function factorial(n) {
13+
if (n < 0) {
14+
return undefined;
15+
}
16+
if (n === 1 || n === 0) {
17+
return 1;
18+
}
19+
return n * factorial(n - 1);
20+
}

src/js/others/fibonacci.js

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
export function fibonacci(n) {
2+
if (n < 1) {
3+
return 0;
4+
}
5+
if (n <= 2) {
6+
return 1;
7+
}
8+
return fibonacci(n - 1) + fibonacci(n - 2);
9+
}
10+
11+
export function fibonacciIterative(n) {
12+
if (n < 1) { return 0; }
13+
let fibNMinus2 = 0;
14+
let fibNMinus1 = 1;
15+
let fibN = n;
16+
for (let i = 2; i <= n; i++) {
17+
fibN = fibNMinus1 + fibNMinus2;
18+
fibNMinus2 = fibNMinus1;
19+
fibNMinus1 = fibN;
20+
}
21+
return fibN;
22+
}
23+
24+
export function fibonacciMemoization(n) {
25+
if (n < 1) { return 0; }
26+
const memo = [0, 1];
27+
const fibonacciMem = num => {
28+
if (memo[num] != null) { return memo[num]; }
29+
memo[num] = fibonacciMem(num - 1) + fibonacciMem(num - 2);
30+
return (memo[num] = fibonacciMem(num - 1) + fibonacciMem(num - 2));
31+
};
32+
return fibonacciMem(n);
33+
}

src/ts/index.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as _util from './util';
2+
export const util = _util;
23

34
export { default as LinkedList } from './data-structures/linked-list';
45
export { default as DoublyLinkedList } from './data-structures/doubly-linked-list';
@@ -12,7 +13,12 @@ export { default as HashTableSeparateChaining } from './data-structures/hash-tab
1213
export { default as HashTableLinearProbing } from './data-structures/hash-table-linear-probing';
1314
export { default as HashTableLinearProbingLazy } from './data-structures/hash-table-linear-probing-lazy';
1415

15-
export const util = _util;
16+
// chapter 08
17+
export { factorialIterative as factorialIterative } from './others/factorial';
18+
export { factorial as factorial} from './others/factorial';
19+
export { fibonacci as fibonacci} from './others/fibonacci';
20+
export { fibonacciIterative as fibonacciIterative} from './others/fibonacci';
21+
export { fibonacciMemoization as fibonacciMemoization} from './others/fibonacci';
1622

1723

1824
/* import { hotPotato } from './others/hot-potato';

src/ts/others/factorial.ts

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
export function factorialIterative(number: number) {
2+
if (number < 0) {
3+
return undefined;
4+
}
5+
let total = 1;
6+
for (let n = number; n > 1; n--) {
7+
total = total * n;
8+
}
9+
return total;
10+
}
11+
12+
export function factorial(n: number): number {
13+
if (n < 0) {
14+
return undefined;
15+
}
16+
if (n === 1 || n === 0) {
17+
return 1;
18+
}
19+
return n * factorial(n - 1);
20+
}

src/ts/others/fibonacci.ts

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
export function fibonacci(n: number): number {
2+
if (n < 1) { return 0; } // {1}
3+
if (n <= 2) { return 1; } // {2}
4+
return fibonacci(n - 1) + fibonacci(n - 2); // {3}
5+
}
6+
7+
export function fibonacciIterative(n: number) {
8+
if (n < 1) { return 0; }
9+
let fibNMinus2 = 0;
10+
let fibNMinus1 = 1;
11+
let fibN = n;
12+
for (let i = 2; i <= n; i++) {
13+
// n >= 2
14+
fibN = fibNMinus1 + fibNMinus2; // f(n-1) + f(n-2)
15+
fibNMinus2 = fibNMinus1;
16+
fibNMinus1 = fibN;
17+
}
18+
return fibN;
19+
}
20+
21+
export function fibonacciMemoization(n: number) {
22+
if (n < 1) { return 0; }
23+
const memo = [0, 1];
24+
const fibonacciMem = (num: number): number => {
25+
if (memo[num] != null) { return memo[num]; }
26+
return (memo[num] = fibonacciMem(num - 1) + fibonacciMem(num - 2));
27+
};
28+
return fibonacciMem(n);
29+
}

test/js/others/factorial.spec.js

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import 'mocha';
2+
import { expect } from 'chai';
3+
import { factorialIterative, factorial } from './../../../src/js/others/factorial';
4+
5+
describe('Factorial', () => {
6+
it('Iterative Factorial', () => {
7+
expect(factorialIterative(-1)).to.equal(undefined);
8+
expect(factorialIterative(0)).to.equal(1);
9+
expect(factorialIterative(1)).to.equal(1);
10+
expect(factorialIterative(2)).to.equal(2);
11+
expect(factorialIterative(3)).to.equal(6);
12+
expect(factorialIterative(4)).to.equal(24);
13+
expect(factorialIterative(5)).to.equal(120);
14+
});
15+
16+
it('Recursive Factorial', () => {
17+
expect(factorial(-1)).to.equal(undefined);
18+
expect(factorial(0)).to.equal(1);
19+
expect(factorial(1)).to.equal(1);
20+
expect(factorial(2)).to.equal(2);
21+
expect(factorial(3)).to.equal(6);
22+
expect(factorial(4)).to.equal(24);
23+
expect(factorial(5)).to.equal(120);
24+
});
25+
});

test/js/others/fibonacci.spec.js

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import 'mocha';
2+
import { expect } from 'chai';
3+
import {
4+
fibonacci,
5+
fibonacciIterative,
6+
fibonacciMemoization
7+
} from '../../../src/js/others/fibonacci';
8+
9+
describe('Fibonacci', () => {
10+
it('Fibonacci Recursive', () => {
11+
expect(fibonacci(-1)).to.equal(0);
12+
expect(fibonacci(0)).to.equal(0);
13+
expect(fibonacci(1)).to.equal(1);
14+
expect(fibonacci(2)).to.equal(1);
15+
expect(fibonacci(3)).to.equal(2);
16+
expect(fibonacci(4)).to.equal(3);
17+
});
18+
19+
it('Fibonacci Iterative', () => {
20+
expect(fibonacciIterative(-1)).to.equal(0);
21+
expect(fibonacciIterative(0)).to.equal(0);
22+
expect(fibonacciIterative(1)).to.equal(1);
23+
expect(fibonacciIterative(2)).to.equal(1);
24+
expect(fibonacciIterative(3)).to.equal(2);
25+
expect(fibonacciIterative(4)).to.equal(3);
26+
});
27+
28+
it('Fibonacci with Memoization', () => {
29+
expect(fibonacciMemoization(-1)).to.equal(0);
30+
expect(fibonacciMemoization(0)).to.equal(0);
31+
expect(fibonacciMemoization(1)).to.equal(1);
32+
expect(fibonacciMemoization(2)).to.equal(1);
33+
expect(fibonacciMemoization(3)).to.equal(2);
34+
expect(fibonacciMemoization(4)).to.equal(3);
35+
});
36+
});

0 commit comments

Comments
 (0)