├── .gitignore ├── LICENSE ├── README.md ├── chapters ├── chapter-1-fundamentals │ ├── 1.1-programming-model │ │ ├── .gitkeep │ │ └── BinarySearch.js │ ├── 1.2-data-abstraction │ │ └── .gitkeep │ ├── 1.3-bags-queues-ans-stacks │ │ ├── .gitkeep │ │ └── evaluate.js │ ├── 1.4-analysis-of-algorithms │ │ ├── .gitkeep │ │ ├── threeSum.js │ │ ├── threeSumFast.js │ │ ├── twoSum.js │ │ └── twoSumFast.js │ └── 1.5-case-study-union-find │ │ ├── .gitkeep │ │ ├── quickUnion.js │ │ ├── unionFind.js │ │ └── weightedQuickUnion.js ├── chapter-2-sorting │ ├── 2.1-elementary-sorts │ │ ├── .gitkeep │ │ ├── bubble.js │ │ ├── insertion.js │ │ ├── selection.js │ │ └── shell.js │ ├── 2.2-mergesort │ │ ├── .gitkeep │ │ ├── merge.js │ │ ├── mergeRecursiveBottom2Top.js │ │ └── mergeRecursiveTop2Bottom.js │ ├── 2.3-quicksort │ │ ├── .gitkeep │ │ ├── quick3way.js │ │ ├── quicksort.js │ │ └── quicksortImprove.js │ ├── 2.4-priority-queues │ │ ├── .gitkeep │ │ ├── heapSort.js │ │ ├── priorityQueueAdd.js │ │ └── priorityQueueDelete.js │ └── 2.5-applications │ │ └── .gitkeep ├── chapter-3-searching │ ├── 3.1-elementary-symbol-tables │ │ ├── .gitkeep │ │ ├── binarySearchST.js │ │ └── sequentialSearchST.js │ ├── 3.2-binary-search-trees │ │ ├── .gitkeep │ │ └── binarySearchTree.js │ ├── 3.3-balanced-search-trees │ │ └── .gitkeep │ ├── 3.4-hash-tables │ │ └── .gitkeep │ └── 3.5-applications │ │ └── .gitkeep ├── chapter-4-graphs │ ├── 4.1-undirected-graphs │ │ └── .gitkeep │ ├── 4.2-directed-graphs │ │ └── .gitkeep │ ├── 4.3-minimum-spanning-trees │ │ └── .gitkeep │ └── 4.4-shortest-paths │ │ └── .gitkeep ├── chapter-5-strings │ ├── 5.1-string-sorts │ │ └── .gitkeep │ ├── 5.2-tries │ │ └── .gitkeep │ ├── 5.3-substring-search │ │ └── .gitkeep │ ├── 5.4-regular-expressions │ │ └── .gitkeep │ └── 5.5-data-compression │ │ └── .gitkeep └── chapter-6-context │ └── .gitkeep └── generator ├── build.js ├── checker.js ├── create.js ├── file.xtpl └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | *.log 3 | 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 小胡子哥 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Algorithms in JavaScript 2 | --- 3 | 4 | **[Detail & Discusion (讨论和细节)](https://github.com/barretlee/algorithms/issues)** 5 | 6 | All algorithms writing with JavaScript in book '[Algorithms Fourth Edition](http://www.amazon.com/Algorithms-4th-Robert-Sedgewick/dp/032157351X?ie=UTF8&keywords=Algorithms%20Fourth%20Edition&qid=1464068185&ref_=sr_1_1&sr=8-1)'. 7 | 8 | ### Usage 9 | 10 | Run `generator/create.js` to generate code template. 11 | 12 | ```bash 13 | # create a file with `file.xtpl` at `chapter/chapter-1-xxx/1.2-xxx/test.js` 14 | node generator/create 1.2/test 15 | 16 | # delete file `chapter/chapter-1-xxx/1.2-xxx/test.js` if exists 17 | node generator/create 1.2/test -d 18 | ``` 19 | 20 | The template is: 21 | 22 | ```javascript 23 | console.log('<%- fileName %>:') 24 | /* input start */ 25 | var input = require('../../../generator/index').getRandomNumbers(); 26 | /* input end */ 27 | console.log('> input: ' + input); 28 | 29 | 30 | // <%- fileName %> 31 | function <%- fileName %>(input) { 32 | var output; 33 | return output; 34 | } 35 | 36 | 37 | /* output start */ 38 | console.log('> output: ' + <%- fileName %>(input)); 39 | /* output end */ 40 | ``` 41 | 42 | There are many functions in `genetator/index` for generating data. such as: 43 | 44 | ```javascript 45 | var input = require('./generator/index').getRandomNumbers(); 46 | // -> [random numbers which length is default 20 between 0 to 1E5] 47 | ``` 48 | 49 | 50 | ### License 51 | 52 | The MIT License (MIT) 53 | 54 | Copyright (c) 2016 小胡子哥 -------------------------------------------------------------------------------- /chapters/chapter-1-fundamentals/1.1-programming-model/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barretlee/algorithms/d2c9aee5ca145e03fed2a60b8338bc2828d21279/chapters/chapter-1-fundamentals/1.1-programming-model/.gitkeep -------------------------------------------------------------------------------- /chapters/chapter-1-fundamentals/1.1-programming-model/BinarySearch.js: -------------------------------------------------------------------------------- 1 | console.log("BinarySearch:") 2 | /* input start */ 3 | var Generator = require('../../../generator/index'); 4 | var input = Generator.getEscRandomNumbers(10); 5 | var index = Generator.getRandomNumber(0, input.length - 1); 6 | var key = input[index]; 7 | /* input end */ 8 | console.log("> input: " + input + " (index: " + index + ", key: " + key + ")"); 9 | 10 | 11 | // BinarySearch 12 | function BinarySearch(input, key) { 13 | 14 | return indexOf(input, key); 15 | 16 | function indexOf(a, k) { 17 | var start = 0; 18 | var end = a.length - 1; 19 | while(start <= end) { 20 | var mid = Math.floor((end - start) / 2) + start; 21 | if(k < a[mid]) { 22 | end = mid - 1; 23 | } else if(k > a[mid]) { 24 | start = mid + 1; 25 | } else { 26 | return mid; 27 | } 28 | } 29 | return -1; 30 | } 31 | } 32 | 33 | 34 | /* output start */ 35 | console.log("> output: " + BinarySearch(input, key)); 36 | /* output end */ 37 | -------------------------------------------------------------------------------- /chapters/chapter-1-fundamentals/1.2-data-abstraction/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barretlee/algorithms/d2c9aee5ca145e03fed2a60b8338bc2828d21279/chapters/chapter-1-fundamentals/1.2-data-abstraction/.gitkeep -------------------------------------------------------------------------------- /chapters/chapter-1-fundamentals/1.3-bags-queues-ans-stacks/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barretlee/algorithms/d2c9aee5ca145e03fed2a60b8338bc2828d21279/chapters/chapter-1-fundamentals/1.3-bags-queues-ans-stacks/.gitkeep -------------------------------------------------------------------------------- /chapters/chapter-1-fundamentals/1.3-bags-queues-ans-stacks/evaluate.js: -------------------------------------------------------------------------------- 1 | console.log('evaluate:') 2 | /* input start */ 3 | var input = '( 1 + ( ( 2 + 3 ) * ( 4 + 5 ) ) )'; 4 | input = input.replace(/\s/g, '').split(''); 5 | /* input end */ 6 | console.log('> input: ' + input.join(' ')); 7 | 8 | 9 | // evaluate 10 | function evaluate(input) { 11 | input = input.reverse(); 12 | var len = input.length; 13 | var optStack = []; 14 | var valStack = []; 15 | while(len--) { 16 | var item = input[len]; 17 | switch(item) { 18 | case "+": 19 | case "-": 20 | case "*": 21 | case "/": 22 | optStack.push(item); 23 | break; 24 | case "(": 25 | break; 26 | case ")": 27 | var a = valStack.pop(); 28 | var b = valStack.pop(); 29 | var opt = optStack.pop(); 30 | valStack.push(eval(b + opt + a)); 31 | break; 32 | default: 33 | valStack.push(item); 34 | } 35 | } 36 | return valStack.pop(); 37 | } 38 | 39 | 40 | /* output start */ 41 | console.log('> output: ' + evaluate(input)); 42 | /* output end */ 43 | -------------------------------------------------------------------------------- /chapters/chapter-1-fundamentals/1.4-analysis-of-algorithms/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barretlee/algorithms/d2c9aee5ca145e03fed2a60b8338bc2828d21279/chapters/chapter-1-fundamentals/1.4-analysis-of-algorithms/.gitkeep -------------------------------------------------------------------------------- /chapters/chapter-1-fundamentals/1.4-analysis-of-algorithms/threeSum.js: -------------------------------------------------------------------------------- 1 | console.log('threeSum:') 2 | /* input start */ 3 | var Generator = require('../../../generator/index'); 4 | var input = Generator.getRandomNumbers(1E2, -100, 100); 5 | input = Generator.noRepeat(input); 6 | /* input end */ 7 | console.log('> input: ' + input); 8 | 9 | 10 | // threeSum 11 | function threeSum(input) { 12 | var counter = 0; 13 | for(var i = 0, len = input.length; i < len - 2; i++) { 14 | for(var j = i + 1; j < len - 1; j++) { 15 | for(var k = j + 1; k < len; k++) { 16 | if(input[i] + input[j] + input[k] == 0) { 17 | counter++; 18 | } 19 | } 20 | } 21 | } 22 | return counter; 23 | } 24 | 25 | 26 | /* output start */ 27 | console.log('> output: ' + threeSum(input)); 28 | /* output end */ 29 | -------------------------------------------------------------------------------- /chapters/chapter-1-fundamentals/1.4-analysis-of-algorithms/threeSumFast.js: -------------------------------------------------------------------------------- 1 | console.log('threeSumFast:') 2 | /* input start */ 3 | var Generator = require('../../../generator/index'); 4 | var input = Generator.getEscRandomNumbers(1E4, -100, 100); 5 | input = Generator.noRepeat(input); 6 | /* input end */ 7 | console.log('> input: ' + input); 8 | 9 | 10 | // threeSumFast 11 | function threeSumFast(input) { 12 | var counter = 0; 13 | for(var i = 0, len = input.length; i < len - 2; i++) { 14 | for(var j = i + 1; j < len - 1; j++) { 15 | var searchKey = -1 * (input[i] + input[j]); 16 | var key = rank(input, searchKey) 17 | if(key > -1 && key > i && key > j) { 18 | counter++; 19 | } 20 | } 21 | } 22 | return counter; 23 | 24 | function rank(a, k){ 25 | var start = 0; 26 | var end = a.length - 1; 27 | while(start <= end) { 28 | var mid = Math.floor((end - start) / 2) + start; 29 | if(k < a[mid]) { 30 | end = mid - 1; 31 | } else if(k > a[mid]) { 32 | start = mid + 1; 33 | } else { 34 | return mid; 35 | } 36 | } 37 | return -1; 38 | } 39 | } 40 | 41 | 42 | /* output start */ 43 | console.log('> output: ' + threeSumFast(input)); 44 | /* output end */ 45 | -------------------------------------------------------------------------------- /chapters/chapter-1-fundamentals/1.4-analysis-of-algorithms/twoSum.js: -------------------------------------------------------------------------------- 1 | console.log('twoSum:') 2 | /* input start */ 3 | var Generator = require('../../../generator/index'); 4 | var input = Generator.getRandomNumbers(1E4, -10, 10); 5 | input = Generator.noRepeat(input); 6 | /* input end */ 7 | console.log('> input: ' + input); 8 | 9 | 10 | // twoSum 11 | function twoSum(input) { 12 | var counter = 0; 13 | for(var i = 0, len = input.length; i < len - 1; i++) { 14 | for(var j = i + 1; j < len; j++) { 15 | if(input[i] + input[j] == 0) { 16 | counter++; 17 | } 18 | } 19 | } 20 | return counter; 21 | } 22 | 23 | 24 | /* output start */ 25 | console.log('> output: ' + twoSum(input)); 26 | /* output end */ 27 | -------------------------------------------------------------------------------- /chapters/chapter-1-fundamentals/1.4-analysis-of-algorithms/twoSumFast.js: -------------------------------------------------------------------------------- 1 | console.log('twoSumFast:') 2 | /* input start */ 3 | var Generator = require('../../../generator/index'); 4 | var input = Generator.getEscRandomNumbers(1E4, -10, 10); 5 | input = Generator.noRepeat(input); 6 | /* input end */ 7 | console.log('> input: ' + input); 8 | 9 | 10 | // twoSumFast 11 | function twoSumFast(input) { 12 | var counter = 0; 13 | for(var i = 0, len = input.length; i < len - 1; i++) { 14 | var searchKey = -1 * input[i]; 15 | // 排除重复 16 | if(rank(input, searchKey) > -1 && input[i] < 0) { 17 | counter++; 18 | } 19 | } 20 | return counter; 21 | 22 | function rank(a, k){ 23 | var start = 0; 24 | var end = a.length - 1; 25 | while(start <= end) { 26 | var mid = Math.floor((end - start) / 2) + start; 27 | if(k < a[mid]) { 28 | end = mid - 1; 29 | } else if(k > a[mid]) { 30 | start = mid + 1; 31 | } else { 32 | return mid; 33 | } 34 | } 35 | return -1; 36 | } 37 | } 38 | 39 | 40 | /* output start */ 41 | console.log('> output: ' + twoSumFast(input)); 42 | /* output end */ 43 | -------------------------------------------------------------------------------- /chapters/chapter-1-fundamentals/1.5-case-study-union-find/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barretlee/algorithms/d2c9aee5ca145e03fed2a60b8338bc2828d21279/chapters/chapter-1-fundamentals/1.5-case-study-union-find/.gitkeep -------------------------------------------------------------------------------- /chapters/chapter-1-fundamentals/1.5-case-study-union-find/quickUnion.js: -------------------------------------------------------------------------------- 1 | console.log('quickUnion:') 2 | /* input start */ 3 | var Generator = require('../../../generator/index'); 4 | var input = []; 5 | for(var i = 0; i < 20; i++) { 6 | input.push(i); 7 | } 8 | var combo = []; 9 | for(var i = 0; i < 30; i++) { 10 | combo.push(Generator.getEscRandomNumbers(2, 0, input.length).join(',')); 11 | } 12 | combo = Generator.noRepeat(combo); 13 | combo = combo.map(function(item) { 14 | return item.split(','); 15 | }).filter(function(item) { 16 | return item[0] != item[1]; 17 | }); 18 | /* input end */ 19 | console.log('> input: ' + input + '\n combo: ' + combo.join('|')); 20 | 21 | 22 | // quickUnion 23 | function quickUnion(input, combo) { 24 | for(var i = 0, len = combo.length; i < len; i++) { 25 | var p = combo[i][0]; 26 | var q = combo[i][1]; 27 | if(root(p) != root(q)) { 28 | input[p] = q; 29 | } 30 | } 31 | 32 | return input; 33 | 34 | function root(n) { 35 | while(input[n] != n) { 36 | n = input[n]; 37 | } 38 | return n; 39 | } 40 | } 41 | 42 | 43 | /* output start */ 44 | console.log('> output: ' + quickUnion(input, combo)); 45 | /* output end */ 46 | -------------------------------------------------------------------------------- /chapters/chapter-1-fundamentals/1.5-case-study-union-find/unionFind.js: -------------------------------------------------------------------------------- 1 | console.log('unionFind:') 2 | /* input start */ 3 | var Generator = require('../../../generator/index'); 4 | var input = []; 5 | for(var i = 0; i < 20; i++) { 6 | input.push(i); 7 | } 8 | var combo = []; 9 | for(var i = 0; i < 30; i++) { 10 | combo.push(Generator.getEscRandomNumbers(2, 0, input.length).join(',')); 11 | } 12 | combo = Generator.noRepeat(combo); 13 | combo = combo.map(function(item) { 14 | return item.split(','); 15 | }).filter(function(item) { 16 | return item[0] != item[1]; 17 | }); 18 | /* input end */ 19 | console.log('> input: ' + input + '\n combo: ' + combo.join('|')); 20 | 21 | 22 | // unionFind 23 | function unionFind(input, combo) { 24 | for(var i = 0, len = combo.length; i < len; i++) { 25 | var p = combo[i][0]; 26 | var q = combo[i][1]; 27 | if(input[p] == input[q]) { 28 | continue; 29 | } 30 | for(var j = 0, len = input.length; j < len; j++) { 31 | if(input[j] === input[q]) { 32 | input[j] = input[p]; 33 | } 34 | } 35 | } 36 | 37 | return input; 38 | } 39 | 40 | 41 | /* output start */ 42 | console.log('> output: ' + unionFind(input, combo)); 43 | /* output end */ 44 | -------------------------------------------------------------------------------- /chapters/chapter-1-fundamentals/1.5-case-study-union-find/weightedQuickUnion.js: -------------------------------------------------------------------------------- 1 | console.log('weightedQuickUnion:') 2 | /* input start */ 3 | var Generator = require('../../../generator/index'); 4 | var input = []; 5 | for(var i = 0; i < 20; i++) { 6 | input.push(i); 7 | } 8 | var combo = []; 9 | for(var i = 0; i < 30; i++) { 10 | combo.push(Generator.getEscRandomNumbers(2, 0, input.length).join(',')); 11 | } 12 | combo = Generator.noRepeat(combo); 13 | combo = combo.map(function(item) { 14 | return item.split(','); 15 | }).filter(function(item) { 16 | return item[0] != item[1]; 17 | }); 18 | /* input end */ 19 | console.log('> input: ' + input + '\n combo: ' + combo.join('|')); 20 | 21 | 22 | // weightedQuickUnion 23 | function weightedQuickUnion(input, combo) { 24 | var sz = []; 25 | for(var i = 0, len = input.length; i < len; i++) { 26 | sz.push(1); 27 | } 28 | for(var i = 0, len = combo.length; i < len; i++) { 29 | var p = combo[i][0]; 30 | var q = combo[i][1]; 31 | if(root(p) != root(q)) { 32 | if(sz[p] > sz[q]) { 33 | sz[p] += sz[q]; 34 | input[q] = p; 35 | } else { 36 | sz[q] += sz[p]; 37 | input[p] = q; 38 | } 39 | } 40 | } 41 | 42 | return input; 43 | 44 | function root(n) { 45 | while(input[n] != n) { 46 | n = input[n]; 47 | } 48 | return n; 49 | } 50 | } 51 | 52 | 53 | /* output start */ 54 | console.log('> output: ' + weightedQuickUnion(input, combo)); 55 | /* output end */ 56 | -------------------------------------------------------------------------------- /chapters/chapter-2-sorting/2.1-elementary-sorts/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barretlee/algorithms/d2c9aee5ca145e03fed2a60b8338bc2828d21279/chapters/chapter-2-sorting/2.1-elementary-sorts/.gitkeep -------------------------------------------------------------------------------- /chapters/chapter-2-sorting/2.1-elementary-sorts/bubble.js: -------------------------------------------------------------------------------- 1 | console.log('bubble:') 2 | /* input start */ 3 | var input = require('../../../generator/index').getRandomNumbers(); 4 | /* input end */ 5 | console.log('> input: ' + input); 6 | 7 | 8 | // bubble 9 | function bubble(input) { 10 | for(var i = 0, len = input.length; i < len - 1; i++) { 11 | for(var j = 0; j < len - 1 - i; j++) { 12 | if(input[j] > input[j+1]) { 13 | input[j] = [input[j+1], input[j+1] = input[j]][0]; 14 | } 15 | } 16 | } 17 | return input; 18 | } 19 | 20 | 21 | /* output start */ 22 | console.log('> output: ' + bubble(input)); 23 | /* output end */ 24 | -------------------------------------------------------------------------------- /chapters/chapter-2-sorting/2.1-elementary-sorts/insertion.js: -------------------------------------------------------------------------------- 1 | console.log('insertion:') 2 | /* input start */ 3 | var input = require('../../../generator/index').getRandomNumbers(); 4 | /* input end */ 5 | console.log('> input: ' + input); 6 | 7 | 8 | // insertion 9 | function insertion(input) { 10 | for(var i = 1, len = input.length; i < len; i++) { 11 | var insertion = input[i]; 12 | var j = i; 13 | while (j > 0 && insertion < input[j-1]) { 14 | input[j] = input[j-1]; 15 | j--; 16 | } 17 | input[j] = insertion; 18 | } 19 | return input; 20 | } 21 | 22 | 23 | /* output start */ 24 | console.log('> output: ' + insertion(input)); 25 | /* output end */ 26 | -------------------------------------------------------------------------------- /chapters/chapter-2-sorting/2.1-elementary-sorts/selection.js: -------------------------------------------------------------------------------- 1 | console.log('selection:') 2 | /* input start */ 3 | var input = require('../../../generator/index').getRandomNumbers(); 4 | /* input end */ 5 | console.log('> input: ' + input); 6 | 7 | 8 | // selection 9 | function selection(input) { 10 | for(var i = 0, len = input.length; i < len - 1; i++) { 11 | var min = i; 12 | for(var j = i + 1; j < len; j++) { 13 | if(input[j] < input[min]) { 14 | min = j; 15 | } 16 | } 17 | input[i] = [input[min], input[min] = input[i]][0]; 18 | } 19 | return input; 20 | } 21 | 22 | 23 | /* output start */ 24 | console.log('> output: ' + selection(input)); 25 | /* output end */ 26 | -------------------------------------------------------------------------------- /chapters/chapter-2-sorting/2.1-elementary-sorts/shell.js: -------------------------------------------------------------------------------- 1 | console.log('shell:') 2 | /* input start */ 3 | var input = require('../../../generator/index').getRandomNumbers(); 4 | /* input end */ 5 | console.log('> input: ' + input); 6 | 7 | 8 | // shell 9 | function shell(input) { 10 | var h = 1; 11 | var len = input.length; 12 | while(h < Math.floor(len / 3)) { 13 | h = h * 3 + 1; 14 | } 15 | while(h >= 1) { 16 | for(var i = h; i < len; i++) { 17 | var insertion = input[i]; 18 | var j = i; 19 | while (j > 0 && insertion < input[j-h]) { 20 | input[j] = input[j-h]; 21 | j -= h; 22 | } 23 | input[j] = insertion; 24 | } 25 | h = Math.floor(h / 3); 26 | } 27 | return input; 28 | } 29 | 30 | 31 | /* output start */ 32 | console.log('> output: ' + shell(input)); 33 | /* output end */ 34 | -------------------------------------------------------------------------------- /chapters/chapter-2-sorting/2.2-mergesort/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barretlee/algorithms/d2c9aee5ca145e03fed2a60b8338bc2828d21279/chapters/chapter-2-sorting/2.2-mergesort/.gitkeep -------------------------------------------------------------------------------- /chapters/chapter-2-sorting/2.2-mergesort/merge.js: -------------------------------------------------------------------------------- 1 | console.log('merge:') 2 | /* input start */ 3 | var input1 = require('../../../generator/index').getEscRandomNumbers(6); 4 | var input2 = require('../../../generator/index').getEscRandomNumbers(9); 5 | /* input end */ 6 | console.log('> input1: ' + input1 + '\n input2: ' + input2); 7 | 8 | 9 | // merge 10 | function merge(input1, input2) { 11 | var i = 0, j = 0; 12 | var output = []; 13 | while(i < input1.length || j < input2.length) { 14 | if(i == input1.length) { 15 | output.push(input2[j++]); 16 | continue; 17 | } 18 | if(j == input2.length) { 19 | output.push(input1[i++]); 20 | continue; 21 | } 22 | if(input1[i] < input2[j]) { 23 | output.push(input1[i++]); 24 | } else { 25 | output.push(input2[j++]); 26 | } 27 | } 28 | return output; 29 | } 30 | 31 | 32 | /* output start */ 33 | console.log('> output: ' + merge(input1, input2)); 34 | /* output end */ 35 | -------------------------------------------------------------------------------- /chapters/chapter-2-sorting/2.2-mergesort/mergeRecursiveBottom2Top.js: -------------------------------------------------------------------------------- 1 | console.log('mergeRecursiveBottom2Top:') 2 | /* input start */ 3 | var input = require('../../../generator/index').getRandomNumbers(); 4 | /* input end */ 5 | console.log('> input: ' + input); 6 | 7 | 8 | // mergeRecursiveBottom2Top 9 | function mergeRecursiveBottom2Top(input) { 10 | 11 | return sort(input, 0, input.length - 1); 12 | 13 | function sort(arr) { 14 | for(var sz = 1, len = arr.length; sz < len; sz = sz * 2) { 15 | for(var start = 0; start < len - sz; start += sz * 2) { 16 | arr = merge(arr, start, start + sz - 1, Math.min(start + sz * 2 - 1, len - 1)); 17 | } 18 | } 19 | return arr; 20 | } 21 | 22 | function merge(arr, start, mid, end) { 23 | var i = start, j = mid + 1, tmp = []; 24 | for(var k = start; k <= end; k++) { 25 | tmp[k] = arr[k]; 26 | } 27 | for(k = start; k <= end; k++) { 28 | if(i > mid) { 29 | arr[k] = tmp[j++]; 30 | continue; 31 | } 32 | if(j > end) { 33 | arr[k] = tmp[i++]; 34 | continue; 35 | } 36 | if(tmp[i] < tmp[j]) { 37 | arr[k] = tmp[i++]; 38 | } else { 39 | arr[k] = tmp[j++]; 40 | } 41 | } 42 | return arr; 43 | } 44 | } 45 | 46 | 47 | /* output start */ 48 | console.log('> output: ' + mergeRecursiveBottom2Top(input)); 49 | /* output end */ 50 | -------------------------------------------------------------------------------- /chapters/chapter-2-sorting/2.2-mergesort/mergeRecursiveTop2Bottom.js: -------------------------------------------------------------------------------- 1 | console.log('mergeRecursiveTop2Bottom:') 2 | /* input start */ 3 | var input = require('../../../generator/index').getRandomNumbers(); 4 | /* input end */ 5 | console.log('> input: ' + input); 6 | 7 | 8 | // mergeRecursiveTop2Bottom 9 | function mergeRecursiveTop2Bottom(input) { 10 | 11 | return sort(input, 0, input.length - 1); 12 | 13 | function sort(arr, start, end) { 14 | if(start >= end) { 15 | return; 16 | } 17 | var mid = ((end - start) >> 1) + start; 18 | sort(arr, start, mid); 19 | sort(arr, mid + 1, end); 20 | return merge(arr, start, mid, end); 21 | } 22 | 23 | function merge(arr, start, mid, end) { 24 | var i = start, j = mid + 1, tmp = []; 25 | for(var k = start; k <= end; k++) { 26 | tmp[k] = arr[k]; 27 | } 28 | for(k = start; k <= end; k++) { 29 | if(i > mid) { 30 | arr[k] = tmp[j++]; 31 | continue; 32 | } 33 | if(j > end) { 34 | arr[k] = tmp[i++]; 35 | continue; 36 | } 37 | if(tmp[i] < tmp[j]) { 38 | arr[k] = tmp[i++]; 39 | } else { 40 | arr[k] = tmp[j++]; 41 | } 42 | } 43 | return arr; 44 | } 45 | } 46 | 47 | 48 | /* output start */ 49 | console.log('> output: ' + mergeRecursiveTop2Bottom(input)); 50 | /* output end */ 51 | -------------------------------------------------------------------------------- /chapters/chapter-2-sorting/2.3-quicksort/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barretlee/algorithms/d2c9aee5ca145e03fed2a60b8338bc2828d21279/chapters/chapter-2-sorting/2.3-quicksort/.gitkeep -------------------------------------------------------------------------------- /chapters/chapter-2-sorting/2.3-quicksort/quick3way.js: -------------------------------------------------------------------------------- 1 | console.log('quick3way:') 2 | /* input start */ 3 | var input = require('../../../generator/index').getRandomNumbers(30, 0, 15); 4 | /* input end */ 5 | console.log('> input: ' + input); 6 | 7 | 8 | // quick3way 9 | function quick3way(input) { 10 | sort(0, input.length - 1); 11 | return input; 12 | 13 | function sort(start, end) { 14 | if(start >= end) return; 15 | 16 | var lt = start, gt = end, i = start + 1, v = input[start]; 17 | while(i <= gt) { 18 | if(input[i] < v) { 19 | input[lt] = [input[i], input[i] = input[lt]][0]; 20 | lt++; i++; 21 | } else if(input[i] > v) { 22 | input[gt] = [input[i], input[i] = input[gt]][0]; 23 | gt--; 24 | } else { 25 | i++; 26 | } 27 | } 28 | sort(start, lt - 1); 29 | sort(gt + 1, end); 30 | } 31 | } 32 | 33 | 34 | /* output start */ 35 | console.log('> output: ' + quick3way(input)); 36 | /* output end */ 37 | -------------------------------------------------------------------------------- /chapters/chapter-2-sorting/2.3-quicksort/quicksort.js: -------------------------------------------------------------------------------- 1 | console.log('quicksort:') 2 | /* input start */ 3 | var input = require('../../../generator/index').getRandomNumbers(); 4 | /* input end */ 5 | console.log('> input: ' + input); 6 | 7 | 8 | // quicksort 9 | function quicksort(input) { 10 | 11 | sort(0, input.length - 1); 12 | return input; 13 | 14 | function sort(start, end) { 15 | if(start >= end) { 16 | return; 17 | } 18 | var mid = partition(start, end); 19 | sort(start, mid - 1); 20 | sort(mid + 1, end); 21 | } 22 | 23 | function partition(start, end) { 24 | var i = start, j = end + 1, k = input[start]; 25 | while(true) { 26 | while(input[++i] < k) if( i === end) break; 27 | while(input[--j] > k) if( j === start) break; 28 | if(i >= j) break; 29 | input[i] = [input[j], input[j] = input[i]][0]; 30 | } 31 | input[j] = [input[start], input[start] = input[j]][0]; 32 | return j; 33 | } 34 | } 35 | 36 | 37 | /* output start */ 38 | console.log('> output: ' + quicksort(input)); 39 | /* output end */ 40 | -------------------------------------------------------------------------------- /chapters/chapter-2-sorting/2.3-quicksort/quicksortImprove.js: -------------------------------------------------------------------------------- 1 | console.log('quicksortImprove:') 2 | /* input start */ 3 | var input = require('../../../generator/index').getRandomNumbers(40); 4 | /* input end */ 5 | console.log('> input: ' + input); 6 | 7 | 8 | // quicksortImprove 9 | var delta = 5; 10 | function quicksortImprove(input) { 11 | 12 | sort(0, input.length - 1); 13 | return input; 14 | 15 | function sort(start, end) { 16 | if(start + delta >= end) { 17 | insertion(start, end); 18 | return; 19 | } 20 | var mid = partition(start, end); 21 | sort(start, mid - 1); 22 | sort(mid + 1, end); 23 | } 24 | 25 | function partition(start, end) { 26 | var i = start, j = end + 1, k = input[start]; 27 | while(true) { 28 | while(input[++i] < k) if( i === end) break; 29 | while(input[--j] > k) if( j === start) break; 30 | if(i >= j) break; 31 | input[i] = [input[j], input[j] = input[i]][0]; 32 | } 33 | input[j] = [input[start], input[start] = input[j]][0]; 34 | return j; 35 | } 36 | 37 | function insertion(start, end) { 38 | for(var i = start + 1, len = end - start; i < end; i++) { 39 | for(var j = i; j > start; j--) { 40 | if(input[j] < input[j - 1]) { 41 | input[j] = [input[j - 1], input[j - 1] = input[j]][0]; 42 | } 43 | } 44 | } 45 | } 46 | } 47 | 48 | 49 | /* output start */ 50 | console.log('> output: ' + quicksortImprove(input)); 51 | /* output end */ 52 | -------------------------------------------------------------------------------- /chapters/chapter-2-sorting/2.4-priority-queues/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barretlee/algorithms/d2c9aee5ca145e03fed2a60b8338bc2828d21279/chapters/chapter-2-sorting/2.4-priority-queues/.gitkeep -------------------------------------------------------------------------------- /chapters/chapter-2-sorting/2.4-priority-queues/heapSort.js: -------------------------------------------------------------------------------- 1 | console.log('heapSort:') 2 | /* input start */ 3 | var Generator = require('../../../generator/index'); 4 | var Checker = require('../../../generator/checker'); 5 | var input = Generator.getRandomNumbers(20, 0, 1E2); 6 | input = Generator.noRepeat(input); 7 | input.unshift(''); 8 | /* input end */ 9 | console.log('> input: ' + input); 10 | 11 | 12 | // heapSort 13 | function heapSort(input) { 14 | return sort(input); 15 | 16 | function sort (arr){ 17 | var N = arr.length - 1; 18 | for(var k = N >> 2; k >= 1; k--) { 19 | arr = sink(arr, k, N); 20 | } 21 | while(N > 1) { 22 | arr[1] = [arr[N], arr[N] = arr[1]][0]; 23 | N--; 24 | arr = sink(arr, 1, N); 25 | } 26 | return arr; 27 | } 28 | function sink(arr, k, N) { 29 | while(2 * k <= N) { 30 | var j = 2 * k; 31 | if(j < N && arr[j] < arr[j + 1]) j++; 32 | if(arr[k] >= arr[j]) break; 33 | arr[k] = [arr[j], arr[j] = arr[k]][0]; 34 | k = j; 35 | } 36 | return arr; 37 | } 38 | } 39 | 40 | 41 | /* output start */ 42 | var output = heapSort(input); 43 | console.log('> output: ' + output); 44 | // console.log('> binary head check: ' + Checker.binaryHeadChecker(output)); 45 | /* output end */ 46 | -------------------------------------------------------------------------------- /chapters/chapter-2-sorting/2.4-priority-queues/priorityQueueAdd.js: -------------------------------------------------------------------------------- 1 | console.log('priorityQueueAdd:') 2 | /* input start */ 3 | var Generator = require('../../../generator/index'); 4 | var input = Generator.getEscRandomNumbers(16, 1, 1E2); 5 | input = Generator.noRepeat(input); 6 | /* input end */ 7 | console.log('> input: ' + input); 8 | 9 | 10 | // priorityQueueAdd 11 | function priorityQueueAdd(input) { 12 | var output = []; 13 | 14 | output[1] = input[0]; 15 | for(var i = 1, len = input.length; i < len; i++) { 16 | output = swim(output, input[i]); 17 | } 18 | 19 | return output; 20 | 21 | function swim(arr, val) { 22 | arr.push(val); 23 | var k = arr.length - 1; 24 | while(k > 1 && arr[k >> 1] < arr[k]) { 25 | var p = k >> 1; 26 | arr[p] = [arr[k], arr[k] = arr[p]][0]; 27 | k = p; 28 | } 29 | return arr; 30 | } 31 | } 32 | 33 | 34 | /* output start */ 35 | console.log('> output: ' + priorityQueueAdd(input)); 36 | /* output end */ 37 | -------------------------------------------------------------------------------- /chapters/chapter-2-sorting/2.4-priority-queues/priorityQueueDelete.js: -------------------------------------------------------------------------------- 1 | console.log('priorityQueueDelete:') 2 | /* input start */ 3 | var Generator = require('../../../generator/index'); 4 | var Checker = require('../../../generator/checker'); 5 | var input = Generator.getEscRandomNumbers(16, 1, 1E2); 6 | input = Generator.noRepeat(input); 7 | function priorityQueueAdd(input) { 8 | var output = []; 9 | 10 | output[1] = input[0]; 11 | for(var i = 1, len = input.length; i < len; i++) { 12 | output = swim(output, input[i]); 13 | } 14 | 15 | return output; 16 | 17 | function swim(arr, val) { 18 | arr.push(val); 19 | var k = arr.length - 1; 20 | while(k > 1 && arr[k >> 1] < arr[k]) { 21 | var p = k >> 1; 22 | arr[p] = [arr[k], arr[k] = arr[p]][0]; 23 | k = p; 24 | } 25 | return arr; 26 | } 27 | } 28 | input = priorityQueueAdd(input); 29 | /* input end */ 30 | console.log('> input: ' + input); 31 | 32 | 33 | // priorityQueueDelete 34 | function priorityQueueDelete(input) { 35 | var output = []; 36 | 37 | input.splice(1, 1); 38 | output = sink(input); 39 | 40 | return output; 41 | 42 | function sink(arr) { 43 | arr.splice(1, 0, arr.pop()); 44 | var k = 1, N = arr.length - 1; 45 | while(2 * k <= N) { 46 | var j = 2 * k; 47 | if(j < N && arr[j] < arr[j + 1]) j++; 48 | if(arr[k] >= arr[j]) break; 49 | arr[k] = [arr[j], arr[j] = arr[k]][0]; 50 | k = j; 51 | } 52 | return arr; 53 | } 54 | } 55 | 56 | 57 | /* output start */ 58 | var output = priorityQueueDelete(input); 59 | console.log('> output: ' + output); 60 | console.log('> binary head checker: ' + Checker.binaryHeadChecker(output)); 61 | /* output end */ 62 | -------------------------------------------------------------------------------- /chapters/chapter-2-sorting/2.5-applications/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barretlee/algorithms/d2c9aee5ca145e03fed2a60b8338bc2828d21279/chapters/chapter-2-sorting/2.5-applications/.gitkeep -------------------------------------------------------------------------------- /chapters/chapter-3-searching/3.1-elementary-symbol-tables/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barretlee/algorithms/d2c9aee5ca145e03fed2a60b8338bc2828d21279/chapters/chapter-3-searching/3.1-elementary-symbol-tables/.gitkeep -------------------------------------------------------------------------------- /chapters/chapter-3-searching/3.1-elementary-symbol-tables/binarySearchST.js: -------------------------------------------------------------------------------- 1 | console.log('binarylSearchST:') 2 | /* input start */ 3 | var input = require('../../../generator/index').getRandomNumbers(); 4 | /* input end */ 5 | console.log('> input: ' + input); 6 | 7 | 8 | // binarylSearchST 9 | function binarylSearchST() { 10 | var keys = [], vals = []; 11 | return { 12 | keys: keys, 13 | vals: vals, 14 | put: function(key, val) { 15 | var pos = this.rank(key); 16 | var N = keys.length; 17 | if(pos == 0) { 18 | keys[0] = key; 19 | vals[0] = val; 20 | } 21 | if(pos < N && keys[pos] === key) { 22 | vals[pos] = val; 23 | return; 24 | } 25 | for(var i = N; i >= pos + 1; i--) { 26 | keys[i + 1] = keys[i]; 27 | vals[i + 1] = vals[i]; 28 | } 29 | keys[i] = key; 30 | vals[i] = val; 31 | }, 32 | get: function(key) { 33 | var pos = this.rank(key); 34 | if(pos >= 0) { 35 | return { 36 | key: keys[pos], 37 | val: vals[pos] 38 | } 39 | } 40 | return -1; 41 | }, 42 | rank: function(key) { 43 | var start = 0, end = Math.max(keys.length - 1, 0), mid; 44 | while(start < end) { 45 | mid = ((end - start) >> 1) + start; 46 | if(!keys[mid]) return mid; 47 | if(keys[mid] < key) end = mid - 1; 48 | else if (keys[mid] > key) start = mid + 1; 49 | return mid; 50 | } 51 | return start; 52 | } 53 | } 54 | } 55 | 56 | var st = new binarylSearchST(); 57 | 'www.barretlee.com'.split('').forEach(function(item, index){ 58 | st.put(item, index); 59 | }); 60 | 61 | console.log(st.keys.join(', ')); 62 | console.log(st.vals.join(', ')); 63 | 64 | console.log(st.get('l')); 65 | 66 | 67 | 68 | 69 | /* output start */ 70 | console.log('> output: ' + binarylSearchST(input)); 71 | /* output end */ 72 | 73 | -------------------------------------------------------------------------------- /chapters/chapter-3-searching/3.1-elementary-symbol-tables/sequentialSearchST.js: -------------------------------------------------------------------------------- 1 | console.log('sequentialSearchST:') 2 | /* input start */ 3 | var input = require('../../../generator/index').getRandomNumbers(); 4 | /* input end */ 5 | console.log('> input: ' + input); 6 | 7 | 8 | // sequentialSearchST 9 | function sequentialSearchST() { 10 | 11 | function Node(key, val, next) { 12 | this.key = key; 13 | this.val = val; 14 | this.next = next; 15 | } 16 | 17 | var first = null; 18 | 19 | return { 20 | links: null, 21 | insertWhere: function(node, where) { 22 | var n = new Node(node.key, node.val); 23 | var l = this.links; 24 | if(where) { 25 | while(l) { 26 | if (l.key == where.key || l.val == where.val) { 27 | var ll = l.next; 28 | l.next = n; 29 | n.next = ll; 30 | break; 31 | } 32 | l = l.next; 33 | } 34 | } else { 35 | n.next = l; 36 | this.links = n; 37 | } 38 | return null; 39 | }, 40 | findWhere: function(where) { 41 | var l = this.links; 42 | var depth = 0; 43 | while(l) { 44 | if(l.key == where.key || l.val == where.val) { 45 | var output = { depth: depth }; 46 | for(var key in l) if(key !== 'next') output[key] = l[key]; 47 | return output; 48 | } 49 | depth++; 50 | l = l.next; 51 | } 52 | return -1; 53 | } 54 | } 55 | } 56 | 57 | // function frequencyCounter(input) { 58 | 59 | // var st = new SequentialSearchST(); 60 | // var minLen = 1; 61 | 62 | // for (var i=0; i < input.split(' ').length; i++) { 63 | // var word = input.split(' ')[i]; 64 | // if (word.length < minLen) continue; 65 | // if (!st.contains(word)) st.put(word, 1); 66 | // else st.put(word, st.get(word) + 1); 67 | // } 68 | 69 | // max = ''; 70 | // st.put(max, 0); 71 | // st.keys().forEach(function(word) { 72 | // if (st.get(word) > st.get(max)) max = word; 73 | // }) 74 | 75 | // output = max + ' ' + st.get(max); 76 | // return output 77 | // } 78 | 79 | 80 | var st = new sequentialSearchST(); 81 | 82 | // insert {key: b, val: b} 83 | st.insertWhere({ 84 | key: 'b', 85 | val: 'b' 86 | }); 87 | // insert {key: a, val: a} 88 | st.insertWhere({ 89 | key: 'a', 90 | val: 'a' 91 | }); 92 | // insert {key: r, val: r} before where key = a 93 | st.insertWhere({ 94 | key: 'r', 95 | val: 'r' 96 | }, { 97 | key: 'a' 98 | }); 99 | // insert {key: b, val: b} 100 | st.insertWhere({ 101 | key: 't', 102 | val: 't' 103 | }); 104 | 105 | console.log(JSON.stringify(st.links, null, 2)); 106 | 107 | console.log(st.findWhere({key: 'b'})); 108 | 109 | /* output start */ 110 | console.log('> output: ' + sequentialSearchST(input)); 111 | /* output end */ 112 | -------------------------------------------------------------------------------- /chapters/chapter-3-searching/3.2-binary-search-trees/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barretlee/algorithms/d2c9aee5ca145e03fed2a60b8338bc2828d21279/chapters/chapter-3-searching/3.2-binary-search-trees/.gitkeep -------------------------------------------------------------------------------- /chapters/chapter-3-searching/3.2-binary-search-trees/binarySearchTree.js: -------------------------------------------------------------------------------- 1 | console.log('binarySearchTree:') 2 | /* input start */ 3 | var input = require('../../../generator/index').getRandomNumbers(); 4 | /* input end */ 5 | console.log('> input: ' + input); 6 | 7 | 8 | // binarySearchTree 9 | function binarySearchTree(input) { 10 | var root; 11 | function Node (key, val, N) { 12 | this.key = key; 13 | this.val = val; 14 | this.N = N; 15 | this.left = null; 16 | this.right = null; 17 | } 18 | function size(x) { 19 | if (!x) return 0; 20 | return x.N; 21 | } 22 | function min(x) { 23 | if (!x.left) return x; 24 | return min(x.left); 25 | } 26 | return { 27 | size: function() { 28 | return size(root); 29 | }, 30 | min: function(x) { 31 | return min(x).key; 32 | }, 33 | get: function (x, key) { 34 | if (!x) return null; 35 | if (x.key === key) return x.val; 36 | if (x.key > key) return get(x.right, key); 37 | if (x.key < key) return get(x.right, key); 38 | }, 39 | put: function(x, key, val) { 40 | if (!x) return new x(key, val, 1); 41 | if (x.key === key) x.val = val; 42 | else if (x.key > key) put(x.right, key, val); 43 | else if (x.key < key) put(x.left, key, val); 44 | x.N = size(x.left) + size(x.right) + 1; 45 | return x; 46 | } 47 | 48 | } 49 | return output; 50 | } 51 | 52 | 53 | /* output start */ 54 | console.log('> output: ' + binarySearchTree(input)); 55 | /* output end */ 56 | -------------------------------------------------------------------------------- /chapters/chapter-3-searching/3.3-balanced-search-trees/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barretlee/algorithms/d2c9aee5ca145e03fed2a60b8338bc2828d21279/chapters/chapter-3-searching/3.3-balanced-search-trees/.gitkeep -------------------------------------------------------------------------------- /chapters/chapter-3-searching/3.4-hash-tables/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barretlee/algorithms/d2c9aee5ca145e03fed2a60b8338bc2828d21279/chapters/chapter-3-searching/3.4-hash-tables/.gitkeep -------------------------------------------------------------------------------- /chapters/chapter-3-searching/3.5-applications/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barretlee/algorithms/d2c9aee5ca145e03fed2a60b8338bc2828d21279/chapters/chapter-3-searching/3.5-applications/.gitkeep -------------------------------------------------------------------------------- /chapters/chapter-4-graphs/4.1-undirected-graphs/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barretlee/algorithms/d2c9aee5ca145e03fed2a60b8338bc2828d21279/chapters/chapter-4-graphs/4.1-undirected-graphs/.gitkeep -------------------------------------------------------------------------------- /chapters/chapter-4-graphs/4.2-directed-graphs/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barretlee/algorithms/d2c9aee5ca145e03fed2a60b8338bc2828d21279/chapters/chapter-4-graphs/4.2-directed-graphs/.gitkeep -------------------------------------------------------------------------------- /chapters/chapter-4-graphs/4.3-minimum-spanning-trees/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barretlee/algorithms/d2c9aee5ca145e03fed2a60b8338bc2828d21279/chapters/chapter-4-graphs/4.3-minimum-spanning-trees/.gitkeep -------------------------------------------------------------------------------- /chapters/chapter-4-graphs/4.4-shortest-paths/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barretlee/algorithms/d2c9aee5ca145e03fed2a60b8338bc2828d21279/chapters/chapter-4-graphs/4.4-shortest-paths/.gitkeep -------------------------------------------------------------------------------- /chapters/chapter-5-strings/5.1-string-sorts/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barretlee/algorithms/d2c9aee5ca145e03fed2a60b8338bc2828d21279/chapters/chapter-5-strings/5.1-string-sorts/.gitkeep -------------------------------------------------------------------------------- /chapters/chapter-5-strings/5.2-tries/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barretlee/algorithms/d2c9aee5ca145e03fed2a60b8338bc2828d21279/chapters/chapter-5-strings/5.2-tries/.gitkeep -------------------------------------------------------------------------------- /chapters/chapter-5-strings/5.3-substring-search/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barretlee/algorithms/d2c9aee5ca145e03fed2a60b8338bc2828d21279/chapters/chapter-5-strings/5.3-substring-search/.gitkeep -------------------------------------------------------------------------------- /chapters/chapter-5-strings/5.4-regular-expressions/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barretlee/algorithms/d2c9aee5ca145e03fed2a60b8338bc2828d21279/chapters/chapter-5-strings/5.4-regular-expressions/.gitkeep -------------------------------------------------------------------------------- /chapters/chapter-5-strings/5.5-data-compression/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barretlee/algorithms/d2c9aee5ca145e03fed2a60b8338bc2828d21279/chapters/chapter-5-strings/5.5-data-compression/.gitkeep -------------------------------------------------------------------------------- /chapters/chapter-6-context/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barretlee/algorithms/d2c9aee5ca145e03fed2a60b8338bc2828d21279/chapters/chapter-6-context/.gitkeep -------------------------------------------------------------------------------- /generator/build.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | -------------------------------------------------------------------------------- /generator/checker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Barret Lee 3 | * @description check the accuracy of output data. 4 | * @license MIT 5 | */ 6 | 7 | module.exports = { 8 | /** 9 | * Check whether if it is correct of binary head structure 10 | * @param {Array} output program's output 11 | * @return {Boolean} 12 | */ 13 | binaryHeadChecker: function(output) { 14 | var k = 1, N = output.length - 1; 15 | while(2 * k < N) { 16 | var a = 2 * k; 17 | var b = a + 1; 18 | var pass = output[a] !== undefined && output[b] !== undefined; 19 | if(!pass || Math.max(output[a], output[b]) > output[k]) return 'not pass'; 20 | k = a; 21 | } 22 | return 'pass'; 23 | } 24 | }; -------------------------------------------------------------------------------- /generator/create.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var path = require('path'); 3 | 4 | // node 1.2/test.js 5 | var argv = process.argv; 6 | if(argv.length < 3 || argv.length > 4) { 7 | console.log('Usage: node 1.3/binaryTree (-d)'); 8 | process.exit(0); 9 | } 10 | var del = argv[3] === '-d'; 11 | var name = argv[2].replace(/\.\w+$/, '').split('/')[1]; 12 | var chapterSection = argv[2].replace(/\.\w+$/, '').split('/')[0]; 13 | var chapter = chapterSection.split('.')[0]; 14 | var section = chapterSection.split('.')[1]; 15 | var xtpl = fs.readFileSync(path.join(__dirname, 'file.xtpl')).toString(); 16 | var root = path.join(__dirname, '../chapters'); 17 | xtpl = xtpl.replace(/<%-\s*(\w+?)\s*%>/gm, name); 18 | 19 | fs.readdirSync(root).forEach(function(item) { 20 | if(item.indexOf(chapter) === -1) { 21 | return; 22 | } 23 | fs.readdirSync(path.join(root, item)).forEach(function(s) { 24 | if(s.indexOf(chapterSection) === -1) { 25 | return; 26 | } 27 | var p = path.join(root, item, s, name + '.js'); 28 | if(del) { 29 | if(fs.existsSync(p)) { 30 | console.log('Delete File: ' + p); 31 | fs.unlinkSync(p); 32 | } else { 33 | console.log("File not exists: " + p); 34 | } 35 | } else { 36 | console.log('Create File: ' + p); 37 | fs.writeFileSync(p, xtpl); 38 | } 39 | }) 40 | }) 41 | -------------------------------------------------------------------------------- /generator/file.xtpl: -------------------------------------------------------------------------------- 1 | console.log('<%- fileName %>:') 2 | /* input start */ 3 | var input = require('../../../generator/index').getRandomNumbers(); 4 | /* input end */ 5 | console.log('> input: ' + input); 6 | 7 | 8 | // <%- fileName %> 9 | function <%- fileName %>(input) { 10 | var output; 11 | return output; 12 | } 13 | 14 | 15 | /* output start */ 16 | console.log('> output: ' + <%- fileName %>(input)); 17 | /* output end */ 18 | -------------------------------------------------------------------------------- /generator/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Barret Lee 3 | * @description Base generator of random data. 4 | * @license MIT 5 | */ 6 | 7 | // Default maximum number 8 | var MAX = 1E5; 9 | // Default minimum number 10 | var MIN = 0; 11 | // Default scope of string -> new RegExp("\w") 12 | var STRING = 'ABCDEDFHIJKLMNOPQRSTUVWXYZabcdedfhijklmnopqrstuvwxyz0123456789_'; 13 | // Default amount of random data 14 | var AMOUNT = 20; 15 | 16 | module.exports = { 17 | /** 18 | * product one random number between `min` and `max`. 19 | * @param {Number} min minimum number 20 | * @param {Number} max maximum number 21 | * @return {Number} Random Number 22 | */ 23 | getRandomNumber: function(min, max) { 24 | min = min || MIN; 25 | max = max || MAX; 26 | return Math.floor(Math.random() * (max - min)) + min; 27 | }, 28 | /** 29 | * product one random charactor at the scope of `string`. 30 | * @param {String} string scope of string 31 | * @return {String} a charactor of `string` 32 | */ 33 | getRandomString: function(string) { 34 | string = string || STRING; 35 | return string.charAt(Math.floor(Math.random() * string.length)); 36 | }, 37 | /** 38 | * product `amount` random numbers between `min` and `max`. 39 | * @param {Number} min minimum number 40 | * @param {Number} max maximum number 41 | * @param {Number} amount 42 | * @return {Array} Random Number Array 43 | * 44 | * @example 45 | * getRandomNumbers(); 46 | * getRandomNumbers(amount); 47 | * getRandomNumbers(min, max); 48 | * getRandomNumbers(amount, min, max); 49 | */ 50 | getRandomNumbers: function(/*amount, min, max*/) { 51 | var amount, min, max; 52 | switch(arguments.length) { 53 | case 0: 54 | amount = AMOUNT; 55 | min = MIN; 56 | max = MAX; 57 | break; 58 | case 1: 59 | amount = arguments[0]; 60 | min = MIN; 61 | max = MAX; 62 | break; 63 | case 2: 64 | amount = AMOUNT; 65 | min = arguments[0]; 66 | max = arguments[1]; 67 | break; 68 | case 3: 69 | amount = arguments[0]; 70 | min = arguments[1]; 71 | max = arguments[2]; 72 | break; 73 | default: 74 | throw new Error('Arguments error.'); 75 | } 76 | var arr = []; 77 | while(amount--) { 78 | arr.push(this.getRandomNumber(min, max)); 79 | } 80 | return arr; 81 | }, 82 | /** 83 | * product `amount` random numbers between `min` and `max`, list at desc order. 84 | * @param {Number} min minimum number 85 | * @param {Number} max maximum number 86 | * @param {Number} amount 87 | * @return {Array} 88 | * 89 | * @example 90 | * getDescRandomNumbers(); 91 | * getDescRandomNumbers(amount); 92 | * getDescRandomNumbers(min, max); 93 | * getDescRandomNumbers(amount, min, max); 94 | */ 95 | getDescRandomNumbers: function(/*amount, min, max*/) { 96 | var amount, min, max; 97 | switch(arguments.length) { 98 | case 0: 99 | amount = AMOUNT; 100 | min = MIN; 101 | max = MAX; 102 | break; 103 | case 1: 104 | amount = arguments[0]; 105 | min = MIN; 106 | max = MAX; 107 | break; 108 | case 2: 109 | amount = AMOUNT; 110 | min = arguments[0]; 111 | max = arguments[1]; 112 | break; 113 | case 3: 114 | amount = arguments[0]; 115 | min = arguments[1]; 116 | max = arguments[2]; 117 | break; 118 | default: 119 | throw new Error('Arguments error.'); 120 | } 121 | return this.getRandomNumbers(amount, min, max).sort(function(a, b) { 122 | return a < b ? 1 : -1; 123 | }); 124 | }, 125 | /** 126 | * product `amount` random numbers between `min` and `max`, list at esc order. 127 | * @param {Number} min minimum number 128 | * @param {Number} max maximum number 129 | * @param {Number} amount 130 | * @return {Array} 131 | * 132 | * @example 133 | * getEscRandomNumbers(); 134 | * getEscRandomNumbers(amount); 135 | * getEscRandomNumbers(min, max); 136 | * getEscRandomNumbers(amount, min, max); 137 | */ 138 | getEscRandomNumbers: function(/*amount, min, max*/) { 139 | var amount, min, max; 140 | switch(arguments.length) { 141 | case 0: 142 | amount = AMOUNT; 143 | min = MIN; 144 | max = MAX; 145 | break; 146 | case 1: 147 | amount = arguments[0]; 148 | min = MIN; 149 | max = MAX; 150 | break; 151 | case 2: 152 | amount = AMOUNT; 153 | min = arguments[0]; 154 | max = arguments[1]; 155 | break; 156 | case 3: 157 | amount = arguments[0]; 158 | min = arguments[1]; 159 | max = arguments[2]; 160 | break; 161 | default: 162 | throw new Error('Arguments error.'); 163 | } 164 | return this.getRandomNumbers(amount, min, max).sort(function(a, b) { 165 | return a > b ? 1 : -1; 166 | }); 167 | }, 168 | /** 169 | * product random string at the scope of `string`. 170 | * @param {Number} amount string length 171 | * @param {String} string the scope of string 172 | * @return {String} 173 | * 174 | * @example 175 | * getRandomStrings(); 176 | * getRandomStrings(amount); 177 | * getRandomStrings(string); 178 | * getRandomStrings(amount, string); 179 | */ 180 | getRandomStrings: function(/*amount, string*/) { 181 | var amount, string; 182 | switch(arguments.length) { 183 | case 0: 184 | amount = AMOUNT; 185 | case 1: 186 | if(typeof arguments[0] === 'number') { 187 | amount = arguments[0]; 188 | string = STRING; 189 | } else { 190 | amount = AMOUNT; 191 | string = arguments[0]; 192 | } 193 | break; 194 | case 2: 195 | amount = arguments[0]; 196 | string = arguments[1]; 197 | break; 198 | default: 199 | throw new Error('Arguments error.'); 200 | } 201 | var str = []; 202 | while (amount--) { 203 | str.push(this.getRandomString(string)); 204 | } 205 | return str.join(''); 206 | }, 207 | /** 208 | * get no-repeat data. 209 | * @param {String|Array} 210 | */ 211 | noRepeat: function() { 212 | var ret = [], arr = [], arg = arguments[0]; 213 | arr = arg; 214 | if(typeof arg === 'string') { 215 | arr = arg.split(''); 216 | } 217 | for(var i = 0, len = arr.length; i < len; i++) { 218 | if(ret.indexOf(arr[i]) === -1) { 219 | ret.push(arr[i]); 220 | } 221 | } 222 | return typeof arg === 'string' ? ret.join('') : ret; 223 | } 224 | }; 225 | --------------------------------------------------------------------------------