├── .gitignore ├── LICENSE ├── algs └── sorting │ ├── bubble_sort.js │ ├── bubble_sort.test.js │ ├── bubble_sort_classic.js │ ├── bubble_sort_classic.test.js │ ├── heap_sort.js │ ├── heap_sort.test.js │ ├── insertion_sort.js │ ├── insertion_sort.test.js │ ├── merge_sort.correct.js │ ├── merge_sort.correct.test.js │ ├── merge_sort.js │ ├── merge_sort.test.js │ ├── quick_sort.findNth.js │ ├── quick_sort.js │ ├── quick_sort.shuffle.test.js │ ├── quick_sort.test.js │ ├── selection_sort.js │ ├── selection_sort.test.js │ ├── shell_sort.js │ ├── shell_sort.test.js │ ├── sleep_sort.js │ └── sleep_sort.test.js ├── structures ├── avl_tree.js ├── avl_tree.test.js ├── binary_heap.js ├── binary_heap.test.js ├── binary_tree.js ├── binary_tree.test.js ├── directed_graph.js └── undirected_graph.js └── utils └── array.utils.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 dimko1 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /algs/sorting/bubble_sort.js: -------------------------------------------------------------------------------- 1 | require('./../../utils/array.utils'); 2 | 3 | 4 | 5 | var bubble_sort = function(array){ 6 | var length = array.length; 7 | var swapped = false; 8 | for (var i = 0; i < length; i++){ 9 | swapped = false; 10 | for ( var j = 0; j < length - i - 1; j++){ 11 | if (array[j] > array[j + 1] ){ 12 | array.swap(j, j + 1); 13 | swapped = true; 14 | } 15 | } 16 | 17 | if (!swapped){ 18 | break; 19 | } 20 | } 21 | return array; 22 | }; 23 | 24 | module.exports = bubble_sort; -------------------------------------------------------------------------------- /algs/sorting/bubble_sort.test.js: -------------------------------------------------------------------------------- 1 | require('./../../utils/array.utils'); 2 | var sort_algs = require('./bubble_sort'); 3 | 4 | var array = []; 5 | array.generate_numbers(100); 6 | //soring 100 elements 7 | console.time('100elements'); 8 | sort_algs(array); 9 | console.timeEnd('100elements'); 10 | 11 | //sorting 1000 elements 12 | array.generate_numbers(1000); 13 | console.time('1000elements'); 14 | sort_algs(array); 15 | console.timeEnd('1000elements'); 16 | 17 | //sorting 10000 elements 18 | array.generate_numbers(10000); 19 | console.time('10000elements'); 20 | sort_algs(array); 21 | console.timeEnd('10000elements'); 22 | 23 | //sorting 100000 elements 24 | array.generate_numbers(100000); 25 | console.time('100000elements'); 26 | sort_algs(array); 27 | console.timeEnd('100000elements'); 28 | 29 | -------------------------------------------------------------------------------- /algs/sorting/bubble_sort_classic.js: -------------------------------------------------------------------------------- 1 | require('./../../utils/array.utils'); 2 | 3 | 4 | 5 | var bubble_sort_classic = function(array){ 6 | var length = array.length; 7 | var swapped; 8 | for (var i = 0; i < length; i++){ 9 | swapped = false; 10 | for ( var j = 0; j < length - i - 1; j++){ 11 | if (array[j] > array[j + 1] ){ 12 | array.swap(j, j + 1); 13 | swapped = true; 14 | } 15 | } 16 | 17 | if (!swapped){ 18 | break; 19 | } 20 | } 21 | return array; 22 | }; 23 | 24 | module.exports = bubble_sort_classic; -------------------------------------------------------------------------------- /algs/sorting/bubble_sort_classic.test.js: -------------------------------------------------------------------------------- 1 | require('./../../utils/array.utils'); 2 | var sort_algs = require('./bubble_sort_classic'); 3 | 4 | var array = []; 5 | array.generate_numbers(100); 6 | //soring 100 elements 7 | console.time('100elements'); 8 | sort_algs(array); 9 | console.timeEnd('100elements'); 10 | 11 | //sorting 1000 elements 12 | array.generate_numbers(1000); 13 | console.time('1000elements'); 14 | sort_algs(array); 15 | console.timeEnd('1000elements'); 16 | 17 | //sorting 10000 elements 18 | array.generate_numbers(10000); 19 | console.time('10000elements'); 20 | sort_algs(array); 21 | console.timeEnd('10000elements'); 22 | 23 | //sorting 100000 elements 24 | array.generate_numbers(100000); 25 | console.time('100000elements'); 26 | sort_algs(array); 27 | console.timeEnd('100000elements'); 28 | 29 | -------------------------------------------------------------------------------- /algs/sorting/heap_sort.js: -------------------------------------------------------------------------------- 1 | require('./../../utils/array.utils'); 2 | 3 | 4 | 5 | var heap_sort = function(array){ 6 | 7 | /** 8 | * deeps down to the children, and check if children is less then parent 9 | */ 10 | function sink(array, i, max){ 11 | 12 | var big_index, child; 13 | 14 | while( i < max ) { 15 | big_index = i; 16 | childl = 2 * i + 1; 17 | childr = childl + 1; 18 | 19 | if (childl < max && array[childl] > array[big_index]) 20 | big_index = childl; 21 | 22 | if (childr < max && array[childr] > array[big_index]) 23 | big_index = childr; 24 | 25 | if (big_index == i) return; 26 | 27 | 28 | array.swap(i, big_index); 29 | i = big_index; 30 | } 31 | } 32 | 33 | /** 34 | * build heap from the array 35 | */ 36 | function build_heap(array){ 37 | var index = Math.floor((array.length / 2) - 1) ; 38 | 39 | while ( index >= 0 ){ 40 | sink(array, index, array.length); 41 | index--; 42 | } 43 | } 44 | 45 | /** 46 | * start soring 47 | */ 48 | function heapSort(array){ 49 | build_heap(array); 50 | 51 | var end = array.length - 1; 52 | 53 | while(end >= 0) { 54 | array.swap(0, end); 55 | sink(array, 0, end); 56 | end -= 1 57 | } 58 | 59 | return array; 60 | } 61 | 62 | return heapSort(array); 63 | }; 64 | 65 | module.exports = heap_sort; -------------------------------------------------------------------------------- /algs/sorting/heap_sort.test.js: -------------------------------------------------------------------------------- 1 | require('./../../utils/array.utils'); 2 | var sort_algs = require('./heap_sort'); 3 | 4 | var array = []; 5 | array.generate_numbers(100); 6 | //soring 100 elements 7 | console.time('100elements'); 8 | sort_algs(array); 9 | console.timeEnd('100elements'); 10 | 11 | //sorting 1000 elements 12 | array.generate_numbers(1000); 13 | console.time('1000elements'); 14 | sort_algs(array); 15 | console.timeEnd('1000elements'); 16 | 17 | //sorting 10000 elements 18 | array.generate_numbers(10000); 19 | console.time('10000elements'); 20 | sort_algs(array); 21 | console.timeEnd('10000elements'); 22 | 23 | //sorting 100000 elements 24 | array.generate_numbers(100000); 25 | console.time('100000elements'); 26 | sort_algs(array); 27 | console.timeEnd('100000elements'); 28 | 29 | //sorting 100000 elements 30 | array.generate_numbers(1000000); 31 | console.time('1000000elements'); 32 | sort_algs(array); 33 | console.timeEnd('1000000elements'); 34 | 35 | //sorting 100000 elements 36 | array.generate_numbers(10000000); 37 | console.time('10000000elements'); 38 | sort_algs(array); 39 | console.timeEnd('10000000elements'); 40 | 41 | -------------------------------------------------------------------------------- /algs/sorting/insertion_sort.js: -------------------------------------------------------------------------------- 1 | require('./../../utils/array.utils'); 2 | 3 | 4 | 5 | var insertion_sort = function(array){ 6 | var length = array.length; 7 | 8 | for (var i = 0; i < length; i++){ 9 | 10 | for ( var j = i; j > 0; j--){ 11 | if (array[j] < array[j-1] ){ 12 | array.swap(j, j-1); 13 | } else { 14 | break; 15 | } 16 | } 17 | } 18 | return array; 19 | }; 20 | 21 | module.exports = insertion_sort; -------------------------------------------------------------------------------- /algs/sorting/insertion_sort.test.js: -------------------------------------------------------------------------------- 1 | require('./../../utils/array.utils'); 2 | var sort_algs = require('./insertion_sort'); 3 | 4 | var array = []; 5 | array.generate_numbers(100); 6 | //soring 100 elements 7 | console.time('100elements'); 8 | sort_algs(array); 9 | console.timeEnd('100elements'); 10 | 11 | //sorting 1000 elements 12 | array.generate_numbers(1000); 13 | console.time('1000elements'); 14 | sort_algs(array); 15 | console.timeEnd('1000elements'); 16 | 17 | //sorting 10000 elements 18 | array.generate_numbers(10000); 19 | console.time('10000elements'); 20 | sort_algs(array); 21 | console.timeEnd('10000elements'); 22 | 23 | //sorting 100000 elements 24 | array.generate_numbers(100000); 25 | console.time('100000elements'); 26 | sort_algs(array); 27 | console.timeEnd('100000elements'); 28 | 29 | -------------------------------------------------------------------------------- /algs/sorting/merge_sort.correct.js: -------------------------------------------------------------------------------- 1 | require('./../../utils/array.utils'); 2 | 3 | 4 | 5 | var merge_sort = function(array){ 6 | function merge(a, aux, lo, mid, hi ){ 7 | var result = []; 8 | var il = 0; 9 | var ir = 0; 10 | 11 | for (var k = lo; k <= hi; k++){ 12 | aux[k] = a[k]; 13 | } 14 | debugger; 15 | var i = lo; 16 | var j = mid + 1; 17 | for (var k = lo; k <= hi; k++){ 18 | if ( i > mid) a[k] = aux[j++]; 19 | else if ( j > hi ) a[k] = aux[i++]; 20 | else if ( aux[j] < aux[i]) a[k] = aux[j++]; 21 | else a[k] = aux[i++]; 22 | } 23 | } 24 | 25 | function sort(array, aux, lo, hi){ 26 | if (hi <= lo) return; 27 | var mid = Math.floor(lo + (hi - lo) / 2); 28 | 29 | sort(array, aux, lo, mid); 30 | sort(array, aux, mid + 1, hi); 31 | 32 | merge(array, aux, lo, mid, hi); 33 | } 34 | 35 | function merge_sort(array){ 36 | var aux = array.slice(0); 37 | sort(array, aux, 0, array.length - 1); 38 | return array; 39 | } 40 | 41 | return merge_sort(array); 42 | 43 | }; 44 | 45 | module.exports = merge_sort; 46 | 47 | 48 | -------------------------------------------------------------------------------- /algs/sorting/merge_sort.correct.test.js: -------------------------------------------------------------------------------- 1 | require('./../../utils/array.utils'); 2 | var sort_algs = require('./merge_sort.correct'); 3 | 4 | var array = []; 5 | array.generate_numbers(100); 6 | //soring 100 elements 7 | console.time('100elements'); 8 | sort_algs(array); 9 | console.timeEnd('100elements'); 10 | 11 | //sorting 1000 elements 12 | array.generate_numbers(1000); 13 | console.time('1000elements'); 14 | sort_algs(array); 15 | console.timeEnd('1000elements'); 16 | 17 | //sorting 10000 elements 18 | array.generate_numbers(10000); 19 | console.time('10000elements'); 20 | sort_algs(array); 21 | console.timeEnd('10000elements'); 22 | 23 | //sorting 100000 elements 24 | array.generate_numbers(100000); 25 | console.time('100000elements'); 26 | sort_algs(array); 27 | console.timeEnd('100000elements'); 28 | 29 | //sorting 1000000 elements 30 | array.generate_numbers(1000000); 31 | console.time('1000000elements'); 32 | sort_algs(array); 33 | console.timeEnd('1000000elements'); 34 | 35 | //sorting 10000000 elements 36 | array.generate_numbers(10000000); 37 | console.time('10000000elements'); 38 | sort_algs(array); 39 | console.timeEnd('10000000elements'); 40 | 41 | -------------------------------------------------------------------------------- /algs/sorting/merge_sort.js: -------------------------------------------------------------------------------- 1 | require('./../../utils/array.utils'); 2 | 3 | 4 | 5 | var merge_sort = function(array){ 6 | function merge(left, right){ 7 | var result = []; 8 | var il = 0; 9 | var ir = 0; 10 | 11 | while (il < left.length && ir < right.length){ 12 | if (left[il] < right[ir]){ 13 | result.push(left[il++]); 14 | } else { 15 | result.push(right[ir++]); 16 | } 17 | } 18 | 19 | if ( il < left.length){ 20 | result.push.apply(result,left.slice(il)); 21 | } 22 | 23 | if (ir < right.length){ 24 | result.push.apply(result,right.slice(ir)); 25 | } 26 | 27 | return result; 28 | } 29 | 30 | function merge_sort(items){ 31 | //well it is only 1 element 32 | if (items.length < 2){ 33 | return items; 34 | } 35 | 36 | var middle = Math.floor(items.length / 2); 37 | 38 | //create two arrays 39 | var left = items.slice(0, middle); 40 | var right = items.slice(middle); 41 | 42 | return merge(merge_sort(left), merge_sort(right)); 43 | } 44 | 45 | return merge_sort(array); 46 | 47 | }; 48 | 49 | module.exports = merge_sort; 50 | 51 | 52 | -------------------------------------------------------------------------------- /algs/sorting/merge_sort.test.js: -------------------------------------------------------------------------------- 1 | require('./../../utils/array.utils'); 2 | var sort_algs = require('./merge_sort'); 3 | 4 | var array = []; 5 | array.generate_numbers(100); 6 | //soring 100 elements 7 | console.time('100elements'); 8 | sort_algs(array); 9 | console.timeEnd('100elements'); 10 | 11 | //sorting 1000 elements 12 | array.generate_numbers(1000); 13 | console.time('1000elements'); 14 | sort_algs(array); 15 | console.timeEnd('1000elements'); 16 | 17 | //sorting 10000 elements 18 | array.generate_numbers(10000); 19 | console.time('10000elements'); 20 | sort_algs(array); 21 | console.timeEnd('10000elements'); 22 | 23 | //sorting 100000 elements 24 | array.generate_numbers(100000); 25 | console.time('100000elements'); 26 | sort_algs(array); 27 | console.timeEnd('100000elements'); 28 | 29 | //sorting 1000000 elements 30 | array.generate_numbers(1000000); 31 | console.time('1000000elements'); 32 | sort_algs(array); 33 | console.timeEnd('1000000elements'); 34 | 35 | //sorting 10000000 elements 36 | array.generate_numbers(10000000); 37 | console.time('10000000elements'); 38 | sort_algs(array); 39 | console.timeEnd('10000000elements'); 40 | 41 | -------------------------------------------------------------------------------- /algs/sorting/quick_sort.findNth.js: -------------------------------------------------------------------------------- 1 | //solution shows how to solve tasks of type: find N'th symbol; 2 | 3 | require('./../../utils/array.utils'); 4 | 5 | 6 | 7 | var number_finder = function(array, index){ 8 | function partition(array, lo, hi){ 9 | var i = lo, j = hi + 1; 10 | 11 | while(true){ 12 | while(array[++i] < array[lo]){ 13 | if ( i == hi ) break; 14 | } 15 | 16 | while (array[--j] > array[lo]){ 17 | if ( j == lo ) break; 18 | } 19 | 20 | if (i >= j) break; 21 | 22 | array.swap(i,j); 23 | } 24 | 25 | array.swap(lo,j); 26 | return j; 27 | } 28 | 29 | function findNth(array, lo, hi, index){ 30 | if (hi <= lo && hi == index) { 31 | console.log(array); 32 | return array[hi]; 33 | 34 | } 35 | 36 | var j = partition(array, lo, hi); 37 | console.log(j); 38 | if (j == index){ 39 | if (!array[index]){ 40 | console.log(array); 41 | } 42 | return array[index]; 43 | } 44 | 45 | if ( j < index) { 46 | return findNth(array, j + 1, hi, index); 47 | } 48 | 49 | if ( j > index ){ 50 | return findNth(array, lo, j - 1, index); 51 | } 52 | 53 | return -1; 54 | } 55 | 56 | return findNth(array, 0, array.length-1, index - 1); 57 | } 58 | 59 | module.exports = number_finder; 60 | 61 | 62 | -------------------------------------------------------------------------------- /algs/sorting/quick_sort.js: -------------------------------------------------------------------------------- 1 | require('./../../utils/array.utils'); 2 | 3 | 4 | 5 | var quick_sort = function(array){ 6 | function partition(array, lo, hi){ 7 | var i = lo, j = hi + 1; 8 | 9 | while(true){ 10 | while(array[++i] < array[lo]){ 11 | if ( i == hi ) break; 12 | } 13 | 14 | while (array[--j] > array[lo]){ 15 | if ( j == lo ) break; 16 | } 17 | 18 | if (i >= j) break; 19 | 20 | array.swap(i,j); 21 | } 22 | 23 | array.swap(lo,j); 24 | return j; 25 | } 26 | 27 | function sort(array, lo, hi){ 28 | if (hi <= lo) return; 29 | 30 | var j = partition(array, lo, hi); 31 | 32 | sort(array, lo, j-1); 33 | sort(array, j+1, hi); 34 | } 35 | 36 | function findNth(array, lo, hi, index){ 37 | if (hi <= lo) return; 38 | 39 | var j = partition(array, lo, hi); 40 | 41 | if (j == index) return array[j]; 42 | 43 | if ( j > index) { 44 | return findNth(array, j, hi, index); 45 | } 46 | 47 | if ( j < index ){ 48 | return findNth(array, lo, j, index); 49 | } 50 | 51 | return -1; 52 | } 53 | 54 | 55 | sort(array, 0, array.length - 1); 56 | 57 | return array; 58 | } 59 | 60 | module.exports = quick_sort; 61 | 62 | 63 | -------------------------------------------------------------------------------- /algs/sorting/quick_sort.shuffle.test.js: -------------------------------------------------------------------------------- 1 | require('./../../utils/array.utils'); 2 | var sort_algs = require('./quick_sort'); 3 | 4 | var array = []; 5 | array.generate_numbers(100); 6 | array.knuth_shuffle(); 7 | //soring 100 elements 8 | console.time('100elements'); 9 | sort_algs(array); 10 | console.timeEnd('100elements'); 11 | 12 | //sorting 1000 elements 13 | array.generate_numbers(1000); 14 | array.knuth_shuffle(); 15 | console.time('1000elements'); 16 | sort_algs(array); 17 | console.timeEnd('1000elements'); 18 | 19 | //sorting 10000 elements 20 | array.generate_numbers(10000); 21 | array.knuth_shuffle(); 22 | console.time('10000elements'); 23 | sort_algs(array); 24 | console.timeEnd('10000elements'); 25 | 26 | //sorting 100000 elements 27 | array.generate_numbers(100000); 28 | array.knuth_shuffle(); 29 | console.time('100000elements'); 30 | sort_algs(array); 31 | console.timeEnd('100000elements'); 32 | 33 | //sorting 100000 elements 34 | array.generate_numbers(1000000); 35 | array.knuth_shuffle(); 36 | console.time('1000000elements'); 37 | sort_algs(array); 38 | console.timeEnd('1000000elements'); 39 | 40 | //sorting 100000 elements 41 | array.generate_numbers(10000000); 42 | array.knuth_shuffle(); 43 | console.time('10000000elements'); 44 | sort_algs(array); 45 | console.timeEnd('10000000elements'); 46 | 47 | -------------------------------------------------------------------------------- /algs/sorting/quick_sort.test.js: -------------------------------------------------------------------------------- 1 | require('./../../utils/array.utils'); 2 | var sort_algs = require('./quick_sort'); 3 | 4 | var array = []; 5 | array.generate_numbers(100); 6 | //soring 100 elements 7 | console.time('100elements'); 8 | sort_algs(array); 9 | console.timeEnd('100elements'); 10 | 11 | //sorting 1000 elements 12 | array.generate_numbers(1000); 13 | console.time('1000elements'); 14 | sort_algs(array); 15 | console.timeEnd('1000elements'); 16 | 17 | //sorting 10000 elements 18 | array.generate_numbers(10000); 19 | console.time('10000elements'); 20 | sort_algs(array); 21 | console.timeEnd('10000elements'); 22 | 23 | //sorting 100000 elements 24 | array.generate_numbers(100000); 25 | console.time('100000elements'); 26 | sort_algs(array); 27 | console.timeEnd('100000elements'); 28 | 29 | //sorting 100000 elements 30 | array.generate_numbers(1000000); 31 | console.time('1000000elements'); 32 | sort_algs(array); 33 | console.timeEnd('1000000elements'); 34 | 35 | //sorting 100000 elements 36 | array.generate_numbers(10000000); 37 | console.time('10000000elements'); 38 | sort_algs(array); 39 | console.timeEnd('10000000elements'); 40 | 41 | -------------------------------------------------------------------------------- /algs/sorting/selection_sort.js: -------------------------------------------------------------------------------- 1 | require('./../../utils/array.utils'); 2 | 3 | 4 | var selection_sort = function(array){ 5 | var length = array.length; 6 | 7 | for (var i = 0; i < length; i++){ 8 | var min = i; 9 | 10 | 11 | for (var j = i + 1 ; j < length; j++){ 12 | if (array[min] > array[j]){ 13 | min = j; 14 | } 15 | } 16 | array.swap(i,min); 17 | } 18 | 19 | return array; 20 | }; 21 | 22 | module.exports = selection_sort; -------------------------------------------------------------------------------- /algs/sorting/selection_sort.test.js: -------------------------------------------------------------------------------- 1 | require('./../../utils/array.utils'); 2 | var sort_algs = require('./selection_sort'); 3 | 4 | var array = []; 5 | array.generate_numbers(100); 6 | //soring 100 elements 7 | console.time('100elements'); 8 | sort_algs(array); 9 | console.timeEnd('100elements'); 10 | 11 | //sorting 1000 elements 12 | array.generate_numbers(1000); 13 | console.time('1000elements'); 14 | sort_algs(array); 15 | console.timeEnd('1000elements'); 16 | 17 | //sorting 10000 elements 18 | array.generate_numbers(10000); 19 | console.time('10000elements'); 20 | sort_algs(array); 21 | console.timeEnd('10000elements'); 22 | 23 | //sorting 100000 elements 24 | array.generate_numbers(100000); 25 | console.time('100000elements'); 26 | sort_algs(array); 27 | console.timeEnd('100000elements'); 28 | 29 | -------------------------------------------------------------------------------- /algs/sorting/shell_sort.js: -------------------------------------------------------------------------------- 1 | require('./../../utils/array.utils'); 2 | 3 | var shell_sort = function(array){ 4 | var length = array.length; 5 | var h = 1; 6 | while( h < length / 3){ 7 | h = 3 * h + 1; 8 | } 9 | 10 | while( h > 0 ){ 11 | for ( var i = h; i < length; i++){ 12 | 13 | for ( var j = i; j > 0 && array[j] < array[j-h]; j-=h){ 14 | array.swap(j, j-h); 15 | } 16 | } 17 | //decreasing h 18 | h = --h / 3 19 | 20 | } 21 | return array; 22 | }; 23 | 24 | module.exports = shell_sort; -------------------------------------------------------------------------------- /algs/sorting/shell_sort.test.js: -------------------------------------------------------------------------------- 1 | require('./../../utils/array.utils'); 2 | var sort_algs = require('./shell_sort'); 3 | 4 | var array = []; 5 | array.generate_numbers(100); 6 | //soring 100 elements 7 | console.time('100elements'); 8 | sort_algs(array); 9 | console.timeEnd('100elements'); 10 | 11 | //sorting 1000 elements 12 | array.generate_numbers(1000); 13 | console.time('1000elements'); 14 | sort_algs(array); 15 | console.timeEnd('1000elements'); 16 | 17 | //sorting 10000 elements 18 | array.generate_numbers(10000); 19 | console.time('10000elements'); 20 | sort_algs(array); 21 | console.timeEnd('10000elements'); 22 | 23 | //sorting 100000 elements 24 | array.generate_numbers(100000); 25 | console.time('100000elements'); 26 | sort_algs(array); 27 | console.timeEnd('100000elements'); 28 | 29 | //sorting 1000000 elements 30 | array.generate_numbers(1000000); 31 | console.time('1000000elements'); 32 | sort_algs(array); 33 | console.timeEnd('1000000elements'); 34 | 35 | //sorting 10000000 elements 36 | array.generate_numbers(10000000); 37 | console.time('10000000elements'); 38 | sort_algs(array); 39 | console.timeEnd('10000000elements'); 40 | -------------------------------------------------------------------------------- /algs/sorting/sleep_sort.js: -------------------------------------------------------------------------------- 1 | require('./../../utils/array.utils'); 2 | 3 | 4 | 5 | var sleep_sort = function(array, callback){ 6 | var sorted = [], 7 | sortedTimeout = array.reduce(function(res,el){return res+el;},0); 8 | 9 | array.forEach(function(element){ 10 | setTimeout( 11 | function(){ 12 | sorted.push(element); 13 | }, element); 14 | }); 15 | 16 | setTimeout(function(){ 17 | return callback(sorted); 18 | }, sortedTimeout); 19 | }; 20 | 21 | module.exports = sleep_sort; 22 | -------------------------------------------------------------------------------- /algs/sorting/sleep_sort.test.js: -------------------------------------------------------------------------------- 1 | require('./../../utils/array.utils'); 2 | var sort_algs = require('./sleep_sort'); 3 | 4 | var array = []; 5 | array.generate_numbers(100); 6 | //soring 100 elements 7 | console.time('100elements'); 8 | sort_algs(array, function(array){ 9 | console.log(array); 10 | console.timeEnd('100elements'); 11 | }); 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /structures/avl_tree.js: -------------------------------------------------------------------------------- 1 | /** 2 | * base node object 3 | */ 4 | Node = function(key, value){ 5 | this.key = key; 6 | this.value = value; 7 | this.left = null; 8 | this.right = null; 9 | this.height = 0; 10 | } 11 | 12 | AVLTree = function(){} 13 | 14 | /** 15 | * reference to root node 16 | */ 17 | AVLTree.prototype.root = null; 18 | 19 | /** 20 | * adding node, public interface 21 | */ 22 | AVLTree.prototype.addNode = function(key, value){ 23 | this.root = putNode( this.root, key, value ); 24 | } 25 | 26 | /** 27 | * recursively deletes the node 28 | */ 29 | AVLTree.prototype.deleteNode = function(key){ 30 | this.root = deleteNode(this.root, key); 31 | } 32 | 33 | /** 34 | * simple print function 35 | */ 36 | AVLTree.prototype.print = function(){ 37 | console.log(JSON.stringify(this.root)); 38 | } 39 | 40 | /** 41 | * adding node, by recursively finding it's place using key value 42 | */ 43 | function putNode(node, key, value){ 44 | if ( !node ) return new Node(key, value); 45 | 46 | if (node.key > key ){ 47 | node.left = putNode( node.left, key, value); 48 | } else if (node.key < key) { 49 | node.right = putNode(node.right, key, value); 50 | } else if (node.key == key){ 51 | node.value = value; 52 | } 53 | 54 | node.height = 1 + getSize(node.left) + getSize(node.right); 55 | 56 | return balance(node); 57 | } 58 | 59 | 60 | /** 61 | * corrects height of the node, in case left subtree height and right subtree heigth 62 | * is correct 63 | */ 64 | function correctHeight(node){ 65 | var heightLeft = getSize(node.left); 66 | var heightRight = getSize(node.right); 67 | 68 | 69 | node.height = ( (heightLeft > heightRight) ? heightLeft : heightRight) + 1; 70 | } 71 | 72 | /** 73 | * returns balance factor of the node 74 | */ 75 | function bfactor(node){ 76 | return getSize(node.right) - getSize(node.left); 77 | } 78 | 79 | /** 80 | * function used to balance node 81 | */ 82 | function balance(node){ 83 | correctHeight(node); 84 | if (bfactor(node) == 2){ 85 | 86 | if (bfactor(node.right) < 0){ 87 | node.right = rotateRight(node.right); 88 | } 89 | 90 | return rotateLeft(node); 91 | } 92 | 93 | if (bfactor(node) == -2){ 94 | if (bfactor(node.left) > 0){ 95 | node.left = rotateLeft(node.left); 96 | } 97 | 98 | return rotateRight(node); 99 | } 100 | 101 | return node; 102 | } 103 | 104 | /** 105 | * deletes node 106 | */ 107 | function deleteNode(node, key){ 108 | if (!node) return null; 109 | if (node.key > key) node.left = deleteNode(node.left, key); 110 | else if (node.key < key) node.right = deleteNode(node.right, key); 111 | else { 112 | if (!node.right) return node.left; 113 | if (!node.left) return node.right; 114 | var t = node; 115 | node = getMin(t.right); 116 | node.right = deleteMin(t.right); 117 | node.left = t.left; 118 | 119 | return balance(node); 120 | } 121 | 122 | return balance(node); 123 | 124 | } 125 | 126 | /** 127 | * recursive function used to delete minimal item in the tree 128 | * recuresively we are checking if node has left child. if no - return right child. 129 | * @param {node} node object. 130 | */ 131 | function deleteMin(node){ 132 | if (node.left == null) return node.right; 133 | 134 | node.left = deleteMin(node.left); 135 | node.height = 1 + getSize(node.left) + getSize(node.right); 136 | 137 | return node; 138 | } 139 | 140 | /** 141 | * recursively search for node with minimum key 142 | */ 143 | function getMin(node){ 144 | 145 | if (!node.left) return node; 146 | 147 | return getMin(node.left); 148 | } 149 | 150 | /** 151 | * perform rotation around specific node 152 | */ 153 | function rotateRight(node){ 154 | var tempNode = node.left; 155 | node.left = tempNode.right; 156 | tempNode.right = node; 157 | 158 | correctHeight(node); 159 | correctHeight(tempNode); 160 | 161 | return tempNode; 162 | } 163 | 164 | /** 165 | * perform rotation left around specific node 166 | */ 167 | function rotateLeft(node){ 168 | var tempNode = node.right; 169 | tempNode.right = node.left; 170 | node.left = node; 171 | 172 | correctHeight(node); 173 | correctHeight(tempNode); 174 | 175 | return node; 176 | } 177 | 178 | 179 | /** 180 | * gets node rank 181 | */ 182 | function getSize(node){ 183 | if (!node) return 0; 184 | 185 | return node.height; 186 | } 187 | 188 | module.exports.AVLTree = AVLTree; 189 | 190 | 191 | -------------------------------------------------------------------------------- /structures/avl_tree.test.js: -------------------------------------------------------------------------------- 1 | var AVLTree = require('./avl_tree').AVLTree; 2 | require('./../utils/array.utils'); 3 | 4 | var array = [10,9,8,7,6,5,4,3,2,1,0]; 5 | //array.generate_numbers(100); 6 | 7 | var avl_tree = new AVLTree(); 8 | 9 | array.forEach(function(element){ 10 | avl_tree.addNode(element, element); 11 | }); 12 | 13 | avl_tree.print(); 14 | 15 | avl_tree.deleteNode(7); 16 | 17 | avl_tree.print(); 18 | 19 | 20 | //console.log(binary_tree.getMaxNode().value); 21 | //console.log(binary_tree.getMinNode().value); 22 | 23 | -------------------------------------------------------------------------------- /structures/binary_heap.js: -------------------------------------------------------------------------------- 1 | require('./../utils/array.utils'); 2 | 3 | BinaryHeap = function(){} 4 | 5 | BinaryHeap.prototype.data = []; 6 | 7 | /** 8 | * inserting element into the heap 9 | */ 10 | BinaryHeap.prototype.insert = function(value) { 11 | if (this.data.length == 0) this.data.length = 1; 12 | 13 | this.data[this.data.length] = value; 14 | 15 | this.swim(this.data.length); 16 | } 17 | 18 | /** 19 | * swim element up in the levels of heap 20 | */ 21 | BinaryHeap.prototype.swim = function(k){ 22 | 23 | var current_element = k - 1; 24 | var parent = Math.floor(current_element / 2); 25 | 26 | while ( current_element > 1 && this.data[parent] < this.data[current_element]){ 27 | this.data.swap(current_element, parent); 28 | current_element = parent; 29 | parent = Math.floor(parent / 2); 30 | } 31 | } 32 | 33 | /** 34 | * sink element down 35 | */ 36 | BinaryHeap.prototype.sink = function(k){ 37 | while ( 2 * k < this.data.length){ 38 | var child = 2 * k; 39 | 40 | if ( child < this.data.length && this.data[child] < this.data[child + 1]) child++; 41 | 42 | if (this.data[child] > this.data[k]) this.data.swap(child, k); 43 | 44 | k = child; 45 | } 46 | } 47 | 48 | /** 49 | * returns max number of the heap 50 | */ 51 | BinaryHeap.prototype.getMax = function(){ 52 | var max = this.data[1]; 53 | 54 | this.data.swap(1, this.data.length - 1); 55 | 56 | this.data.length = this.data.length - 1; 57 | 58 | this.sink(1); 59 | 60 | return max; 61 | } 62 | 63 | /** 64 | * returns length of the heap 65 | */ 66 | BinaryHeap.prototype.length = function(){ 67 | return this.data.length; 68 | } 69 | 70 | /** 71 | * print the heap! 72 | */ 73 | BinaryHeap.prototype.print = function(){ 74 | console.log(this.data); 75 | } 76 | 77 | module.exports.BinaryHeap = BinaryHeap; -------------------------------------------------------------------------------- /structures/binary_heap.test.js: -------------------------------------------------------------------------------- 1 | var BinaryHeap = require('./binary_heap').BinaryHeap; 2 | 3 | var array = []; 4 | array.generate_numbers(100); 5 | 6 | var binary_heap = new BinaryHeap(); 7 | 8 | array.forEach(function(element){ 9 | binary_heap.insert(element); 10 | }); 11 | 12 | binary_heap.print(); 13 | 14 | 15 | -------------------------------------------------------------------------------- /structures/binary_tree.js: -------------------------------------------------------------------------------- 1 | /** 2 | * base node object 3 | */ 4 | Node = function(key, value){ 5 | this.key = key; 6 | this.value = value; 7 | this.left = null; 8 | this.right = null; 9 | this.count = 0; 10 | } 11 | 12 | BinaryTree = function(){} 13 | 14 | /** 15 | * reference to root node 16 | */ 17 | BinaryTree.prototype.root = null; 18 | 19 | /** 20 | * adding node, public interface 21 | */ 22 | BinaryTree.prototype.addNode = function(key, value){ 23 | this.root = putNode( this.root, key, value ); 24 | } 25 | 26 | /** 27 | * node search 28 | */ 29 | BinaryTree.prototype.getNode = function(key){ 30 | 31 | var currentNode = this.root; 32 | 33 | while (currentNode != null){ 34 | if (currentNode.key > key) currentNode = currentNode.left; 35 | else if (currentNode.key < key) currentNode = currentNode.right; 36 | else if (currentNode.key == key ) return currentNode; 37 | } 38 | 39 | return null; 40 | } 41 | 42 | /** 43 | * get minimum node 44 | */ 45 | BinaryTree.prototype.getMinNode = function(){ 46 | return getMin(this.root); 47 | } 48 | 49 | /** 50 | * returns max node 51 | */ 52 | BinaryTree.prototype.getMaxNode = function(){ 53 | return getMax(this.root); 54 | } 55 | 56 | /** 57 | * delete minimum node 58 | */ 59 | BinaryTree.prototype.deleteMin = function(){ 60 | deleteMin(this.root); 61 | } 62 | 63 | /** 64 | * finding max e<= key 65 | */ 66 | BinaryTree.prototype.floor = function(key){ 67 | var n = getFloor(this.root, key); 68 | return n; 69 | } 70 | 71 | /** 72 | * finding min e >= key 73 | */ 74 | BinaryTree.prototype.ceil = function(key){ 75 | var n = getCeil(this.root, key); 76 | return n; 77 | } 78 | 79 | /** 80 | * deletes the node 81 | */ 82 | BinaryTree.prototype.deleteNode = function(key){ 83 | this.root = deleteNode(this.root, key); 84 | } 85 | 86 | /** 87 | * pre order traversing 88 | */ 89 | BinaryTree.prototype.preOrder = function() { 90 | preOrder(this.root); 91 | } 92 | 93 | /** 94 | * in order traversing 95 | */ 96 | BinaryTree.prototype.inOrder = function() { 97 | inOrder(this.root); 98 | } 99 | 100 | /** 101 | * post order traversing 102 | */ 103 | BinaryTree.prototype.postOrder = function() { 104 | postOrder(this.root); 105 | } 106 | 107 | /** 108 | * post order traversing 109 | */ 110 | BinaryTree.prototype.bfs = function() { 111 | return bfs(this.root); 112 | } 113 | 114 | function preOrder(node){ 115 | if (node == null) return; 116 | console.log(node.value); 117 | preOrder(node.left); 118 | preOrder(node.right); 119 | } 120 | 121 | function inOrder(node){ 122 | if (node == null) return; 123 | inOrder(node.left); 124 | console.log(node.value); 125 | inOrder(node.right); 126 | } 127 | 128 | function postOrder(node){ 129 | if (node == null) return; 130 | postOrder(node.left); 131 | postOrder(node.right); 132 | console.log(node.value); 133 | } 134 | 135 | function bfs(node){ 136 | var queue = []; 137 | var values = []; 138 | queue.push(node); 139 | 140 | while(queue.length > 0){ 141 | var tempNode = queue.shift(); 142 | values.push(tempNode.value); 143 | if (tempNode.left){ 144 | queue.push(tempNode.left); 145 | } 146 | 147 | if (tempNode.right){ 148 | queue.push(tempNode.right); 149 | } 150 | } 151 | 152 | return values; 153 | } 154 | 155 | /** 156 | * deletes node 157 | */ 158 | function deleteNode(node, key){ 159 | if (!node) return null; 160 | if (node.key > key) node.left = deleteNode(node.left, key); 161 | else if (node.key < key) node.right = deleteNode(node.right, key); 162 | else { 163 | if (!node.right) return node.left; 164 | if (!node.left) return node.right; 165 | var t = node; 166 | node = getMin(t.right); 167 | node.right = deleteMin(t.right); 168 | node.left = t.left; 169 | } 170 | node.count = 1 + getSize(node.left) + getSize(node.right); 171 | return node; 172 | } 173 | 174 | /** 175 | * recursive function used to delete minimal item in the tree 176 | * recuresively we are checking if node has left child. if no - return right child. 177 | * @param {node} node object. 178 | */ 179 | function deleteMin(node){ 180 | if (node.left == null) return node.right; 181 | 182 | node.left = deleteMin(node.left); 183 | node.count = 1 + getSize(node.left) + getSize(node.right); 184 | 185 | return node; 186 | } 187 | 188 | /** 189 | * recursively search for node with minimum key 190 | */ 191 | function getMin(node){ 192 | 193 | if (!node.left) return node; 194 | 195 | return getMin(node.left); 196 | } 197 | 198 | 199 | /** 200 | * recursively search for node with maximum key 201 | */ 202 | function getMax(node){ 203 | 204 | if (!node.right) return node; 205 | 206 | return getMax(node.right); 207 | } 208 | 209 | /** 210 | * get floor element 211 | */ 212 | function getFloor(node, key){ 213 | if ( node == null ) return null; 214 | 215 | if (node.key == key ) return node; 216 | 217 | if (node.key > key) return getFloor(node.left, key); 218 | 219 | var x = getFloor(node.right, key); 220 | 221 | if (x) return x; 222 | 223 | return node; 224 | } 225 | 226 | /** 227 | * get ceil element 228 | */ 229 | function getCeil(node, key){ 230 | 231 | if ( node == null ) return null; 232 | 233 | if (node.key == key ) return node; 234 | 235 | if (node.key < key) return getCeil(node.right, key); 236 | 237 | var x = getCeil(node.left, key); 238 | 239 | if (x) return x; 240 | 241 | return node; 242 | } 243 | 244 | 245 | /** 246 | * adding node, by recursively finding it's place using key value 247 | */ 248 | function putNode(node, key, value){ 249 | if ( !node ) return new Node(key, value); 250 | 251 | if (node.key > key ){ 252 | node.left = putNode( node.left, key, value); 253 | } else if (node.key < key) { 254 | node.right = putNode(node.right, key, value); 255 | } else if (node.key == key){ 256 | node.value = value; 257 | } 258 | 259 | node.count = 1 + getSize(node.left) + getSize(node.right); 260 | 261 | return node; 262 | } 263 | 264 | /** 265 | * gets node rank 266 | */ 267 | function getSize(node){ 268 | if (!node) return 0; 269 | 270 | return node.count; 271 | } 272 | 273 | module.exports.BinaryTree = BinaryTree; 274 | 275 | 276 | -------------------------------------------------------------------------------- /structures/binary_tree.test.js: -------------------------------------------------------------------------------- 1 | var BinaryTree = require('./binary_tree').BinaryTree; 2 | require('./../utils/array.utils'); 3 | 4 | var array = []; 5 | array.generate_numbers(100); 6 | 7 | var binary_tree = new BinaryTree(); 8 | 9 | array.forEach(function(element){ 10 | binary_tree.addNode(element, element); 11 | }); 12 | 13 | console.log(binary_tree.getMaxNode().value); 14 | console.log(binary_tree.getMinNode().value); 15 | 16 | var binary_tree_traversals = new BinaryTree(); 17 | binary_tree_traversals.addNode('F', 'F'); 18 | binary_tree_traversals.addNode('B', 'B'); 19 | binary_tree_traversals.addNode('A', 'A'); 20 | binary_tree_traversals.addNode('D', 'D'); 21 | binary_tree_traversals.addNode('C', 'C'); 22 | binary_tree_traversals.addNode('E', 'E'); 23 | binary_tree_traversals.addNode('G', 'G'); 24 | binary_tree_traversals.addNode('I', 'I'); 25 | binary_tree_traversals.addNode('H', 'H'); 26 | 27 | console.log('---------PRE ORDER----------'); 28 | binary_tree_traversals.preOrder(); 29 | 30 | console.log('---------IN ORDER----------'); 31 | binary_tree_traversals.inOrder(); 32 | 33 | console.log('---------POST ORDER----------'); 34 | binary_tree_traversals.postOrder(); 35 | 36 | console.log('---------BFS----------'); 37 | console.log(binary_tree_traversals.bfs()); -------------------------------------------------------------------------------- /structures/directed_graph.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Structure for representing Directed graph as adjacency list 3 | */ 4 | 5 | var DirectedGraph = function(V){ 6 | this.V = V; 7 | this.adj = []; 8 | for (var v = 0 ; v < V ; v++){ 9 | this.adj[v] = []; 10 | } 11 | }; 12 | 13 | DirectedGraph.prototype.addEdge = function(v,w){ 14 | this.adj[v].push(w); 15 | }; 16 | 17 | DirectedGraph.prototype.getAdj = function(v){ 18 | return this.adj[v]; 19 | }; 20 | 21 | DirectedGraph.prototype.getV = function(){ 22 | return this.V; 23 | }; 24 | 25 | 26 | module.exports.DirectedGraph = DirectedGraph; -------------------------------------------------------------------------------- /structures/undirected_graph.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Structure for representing Undirected graph as adjacency list 3 | */ 4 | 5 | var UndirectedGraph = function(V){ 6 | //nodes 7 | this.V = V; 8 | 9 | //adjacencies 10 | this.adj = []; 11 | for (var v = 0 ; v < V ; v++){ 12 | this.adj[v] = []; 13 | } 14 | }; 15 | 16 | /** 17 | * since graph is undirected, adding adjucency for all nodes 18 | */ 19 | UndirectedGraph.prototype.addEdge = function(v,w){ 20 | this.adj[v].push(w); 21 | this.adj[w].push(v); 22 | }; 23 | 24 | UndirectedGraph.prototype.getAdj = function(v){ 25 | return this.adj[v]; 26 | }; 27 | 28 | UndirectedGraph.prototype.getVectors = function(){ 29 | return this.V; 30 | 31 | }; 32 | 33 | module.exports.UndirectedGraph = UndirectedGraph; -------------------------------------------------------------------------------- /utils/array.utils.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * current function is used to swap two elements in array 4 | * @param {int} a index of the first element 5 | * @param {int} b index of the second element 6 | */ 7 | Array.prototype.swap = function(a,b){ 8 | var tmp = this[a]; 9 | this[a] = this[b]; 10 | this[b] = tmp; 11 | } 12 | 13 | /** 14 | * current function is used to randomly generate numbers 15 | * @param {int} amount - amount of items to henerate 16 | */ 17 | Array.prototype.generate_numbers = function(amount){ 18 | for (var i = 0; i < amount; i++ ){ 19 | this[i] = Math.floor(Math.random() * amount + 1); 20 | } 21 | } 22 | 23 | /** 24 | * current function is used to shuffle array using knuth shuffle algorithm 25 | */ 26 | Array.prototype.knuth_shuffle = function() { 27 | 28 | var random = 0; 29 | for (var i = 1; i < this.length; i++){ 30 | var random = Math.floor(Math.random() * i); 31 | this.swap(i, random); 32 | } 33 | }; 34 | 35 | /** 36 | * function validates array if it is sorted 37 | */ 38 | Array.prototype.validate_sorted = function(){ 39 | for (var i = 0; i < this.length - 1; i++){ 40 | if (this[i] > this[i+1]) 41 | return false; 42 | } 43 | 44 | return true; 45 | }; --------------------------------------------------------------------------------