From 2be287f0472d19bfc42954f8d4ffa0c93263e228 Mon Sep 17 00:00:00 2001 From: nem035 Date: Sun, 22 May 2016 00:44:00 -0400 Subject: [PATCH 1/3] Added binary search algorithm --- algorithm/category.json | 6 + algorithm/search/binary_search/desc.json | 17 +++ .../search/binary_search/recursive/code.js | 33 +++++ .../search/binary_search/recursive/data.js | 3 + js/module/array1d.js | 31 +++-- js/module/array2d.js | 126 ++++++++++++------ 6 files changed, 166 insertions(+), 50 deletions(-) create mode 100644 algorithm/search/binary_search/desc.json create mode 100644 algorithm/search/binary_search/recursive/code.js create mode 100644 algorithm/search/binary_search/recursive/data.js diff --git a/algorithm/category.json b/algorithm/category.json index 2cd49020..81b8abb0 100644 --- a/algorithm/category.json +++ b/algorithm/category.json @@ -6,6 +6,12 @@ "bfs": "BFS" } }, + "search": { + "name": "Search", + "list": { + "binary_search": "Binary Search" + } + }, "sorting": { "name": "Sorting", "list": { diff --git a/algorithm/search/binary_search/desc.json b/algorithm/search/binary_search/desc.json new file mode 100644 index 00000000..6b93323c --- /dev/null +++ b/algorithm/search/binary_search/desc.json @@ -0,0 +1,17 @@ +{ + "Binary Search": "Binary Search is a search algorithm that finds the position of a target value within a sorted array. It works by comparing the target value to the middle element of the array; if they are unequal, the lower or upper half of the array is eliminated depending on the result and the search is repeated in the remaining subarray until it is successful.", + "Applications": [ + "Finding values in a sorted collection", + "Traversing binary search trees" + ], + "Complexity": { + "time": "worst O(log(N)), best O(1), average O(log(N))", + "space": "worst O(log(N)) - recursive, O(1) - iterative" + }, + "References": [ + "Wikipedia" + ], + "files": { + "recursive": "Recursively searching a sorted array" + } +} \ No newline at end of file diff --git a/algorithm/search/binary_search/recursive/code.js b/algorithm/search/binary_search/recursive/code.js new file mode 100644 index 00000000..db860414 --- /dev/null +++ b/algorithm/search/binary_search/recursive/code.js @@ -0,0 +1,33 @@ +function BinarySearch(array, element, minIndex, maxIndex) { // array = sorted array, element = element to be found, minIndex = minIndex index, maxIndex = maxIndex index + var middleIndex = Math.floor((minIndex + maxIndex) / 2); + var testElement = array[middleIndex]; + + tracer._print('Searching at index: ' + middleIndex); + tracer._notify(middleIndex); + + if (testElement < element) { + tracer._print('Going right.'); + return BinarySearch(array, element, middleIndex + 1, maxIndex); + } + + if (testElement > element) { + tracer._print('Going left.'); + return BinarySearch(array, element, minIndex, middleIndex - 1); + } + + if (testElement === element) { + tracer._print(element + ' is found at position ' + middleIndex + '!'); + tracer._select(middleIndex); + return middleIndex; + } + + tracer._print(element + ' is not found!'); + return -1; +} + +var element = D[0]; + +tracer._sleep(1000); +tracer._pace(1000); +tracer._print('Using binary search to find ' + element); +BinarySearch(D, element, 0, D.length - 1); \ No newline at end of file diff --git a/algorithm/search/binary_search/recursive/data.js b/algorithm/search/binary_search/recursive/data.js new file mode 100644 index 00000000..a26af590 --- /dev/null +++ b/algorithm/search/binary_search/recursive/data.js @@ -0,0 +1,3 @@ +var tracer = new Array1DTracer(); +var D = Array1D.randomSorted(15, 0, 50); +tracer._setData(D); \ No newline at end of file diff --git a/js/module/array1d.js b/js/module/array1d.js index 616f6311..390c5522 100644 --- a/js/module/array1d.js +++ b/js/module/array1d.js @@ -6,18 +6,21 @@ Array1DTracer.prototype = Object.create(Array2DTracer.prototype); Array1DTracer.prototype.constructor = Array1DTracer; var Array1D = { - random: function (N, min, max) { + random: function(N, min, max) { return Array2D.random(1, N, min, max)[0]; + }, + randomSorted: function(N, min, max) { + return Array2D.randomSorted(1, N, min, max)[0]; } }; // Override -Array1DTracer.prototype._setData = function (D) { +Array1DTracer.prototype._setData = function(D) { return Array2DTracer.prototype._setData.call(this, [D]); }; // Override -Array1DTracer.prototype._notify = function (idx1, idx2) { +Array1DTracer.prototype._notify = function(idx1, idx2) { if (idx2 === undefined) { Array2DTracer.prototype._notify.call(this, 0, idx1); } else { @@ -26,7 +29,7 @@ Array1DTracer.prototype._notify = function (idx1, idx2) { }; // Override -Array1DTracer.prototype._select = function (s, e) { +Array1DTracer.prototype._select = function(s, e) { if (e === undefined) { Array2DTracer.prototype._select.call(this, 0, s); } else { @@ -35,16 +38,19 @@ Array1DTracer.prototype._select = function (s, e) { }; // Override -Array1DTracer.prototype._selectSet = function (indexes) { +Array1DTracer.prototype._selectSet = function(indexes) { var coords = []; - indexes.forEach(function (index) { - coords.push({x: 0, y: index}); + indexes.forEach(function(index) { + coords.push({ + x: 0, + y: index + }); }); Array2DTracer.prototype._selectSet.call(this, coords); }; // Override -Array1DTracer.prototype._deselect = function (s, e) { +Array1DTracer.prototype._deselect = function(s, e) { if (e === undefined) { Array2DTracer.prototype._deselect.call(this, 0, s); } else { @@ -53,10 +59,13 @@ Array1DTracer.prototype._deselect = function (s, e) { }; // Override -Array1DTracer.prototype._deselectSet = function (indexes) { +Array1DTracer.prototype._deselectSet = function(indexes) { var coords = []; - indexes.forEach(function (index) { - coords.push({x: 0, y: index}); + indexes.forEach(function(index) { + coords.push({ + x: 0, + y: index + }); }); Array2DTracer.prototype._deselectSet.call(this, coords); }; \ No newline at end of file diff --git a/js/module/array2d.js b/js/module/array2d.js index a465683c..45cee352 100644 --- a/js/module/array2d.js +++ b/js/module/array2d.js @@ -12,21 +12,21 @@ Array2DTracer.prototype = Object.create(Tracer.prototype); Array2DTracer.prototype.constructor = Array2DTracer; // Override -Array2DTracer.prototype.resize = function () { +Array2DTracer.prototype.resize = function() { Tracer.prototype.resize.call(this); this.refresh(); }; // Override -Array2DTracer.prototype.clear = function () { +Array2DTracer.prototype.clear = function() { Tracer.prototype.clear.call(this); clearTableColor(); }; var Array2D = { - random: function (N, M, min, max) { + random: function(N, M, min, max) { if (!N) N = 10; if (!M) M = 10; if (min === undefined) min = 1; @@ -39,11 +39,19 @@ var Array2D = { } } return D; + }, + + randomSorted: function(N, M, min, max) { + return this.random(N, M, min, max).map(function(arr) { + return arr.sort(function(a, b) { + return a - b; + }); + }); } }; // Override -Array2DTracer.prototype._setData = function (D) { +Array2DTracer.prototype._setData = function(D) { this.D = D; this.viewX = this.viewY = 0; this.paddingH = 6; @@ -51,8 +59,8 @@ Array2DTracer.prototype._setData = function (D) { this.fontSize = 16; if (Tracer.prototype._setData.call(this, arguments)) { - $('.mtbl-row').each(function (i) { - $(this).children().each(function (j) { + $('.mtbl-row').each(function(i) { + $(this).children().each(function(j) { $(this).text(D[i][j]); }); }); @@ -75,47 +83,65 @@ Array2DTracer.prototype._setData = function (D) { return false; }; -Array2DTracer.prototype._notify = function (x1, y1, x2, y2) { +Array2DTracer.prototype._notify = function(x1, y1, x2, y2) { var second = x2 !== undefined && y2 !== undefined; - this.pushStep({type: 'notifying', x: x1, y: y1, value: this.D[x1][y1]}, !second); - if (second) this.pushStep({type: 'notifying', x: x2, y: y2, value: this.D[x2][y2]}, true); - this.pushStep({type: 'notified', x: x1, y: y1}, false); - if (second) this.pushStep({type: 'notified', x: x2, y: y2}, false); + this.pushStep({ + type: 'notifying', + x: x1, + y: y1, + value: this.D[x1][y1] + }, !second); + if (second) this.pushStep({ + type: 'notifying', + x: x2, + y: y2, + value: this.D[x2][y2] + }, true); + this.pushStep({ + type: 'notified', + x: x1, + y: y1 + }, false); + if (second) this.pushStep({ + type: 'notified', + x: x2, + y: y2 + }, false); }; -Array2DTracer.prototype._select = function (sx, sy, ex, ey) { +Array2DTracer.prototype._select = function(sx, sy, ex, ey) { this.pushSelectingStep('select', null, arguments); }; -Array2DTracer.prototype._selectRow = function (x, sy, ey) { +Array2DTracer.prototype._selectRow = function(x, sy, ey) { this.pushSelectingStep('select', 'row', arguments); }; -Array2DTracer.prototype._selectCol = function (y, sx, ex) { +Array2DTracer.prototype._selectCol = function(y, sx, ex) { this.pushSelectingStep('select', 'col', arguments); }; -Array2DTracer.prototype._selectSet = function (coords) { +Array2DTracer.prototype._selectSet = function(coords) { this.pushSelectingStep('select', 'set', arguments); }; -Array2DTracer.prototype._deselect = function (sx, sy, ex, ey) { +Array2DTracer.prototype._deselect = function(sx, sy, ex, ey) { this.pushSelectingStep('deselect', null, arguments); }; -Array2DTracer.prototype._deselectRow = function (x, sy, ey) { +Array2DTracer.prototype._deselectRow = function(x, sy, ey) { this.pushSelectingStep('deselect', 'row', arguments); }; -Array2DTracer.prototype._deselectCol = function (y, sx, ex) { +Array2DTracer.prototype._deselectCol = function(y, sx, ex) { this.pushSelectingStep('deselect', 'col', arguments); }; -Array2DTracer.prototype._deselectSet = function (coords) { +Array2DTracer.prototype._deselectSet = function(coords) { this.pushSelectingStep('deselect', 'set', arguments); }; -Array2DTracer.prototype.pushSelectingStep = function () { +Array2DTracer.prototype.pushSelectingStep = function() { var args = Array.prototype.slice.call(arguments); var type = args.shift(); var mode = args.shift(); @@ -123,27 +149,47 @@ Array2DTracer.prototype.pushSelectingStep = function () { var coord; switch (mode) { case 'row': - coord = {x: args[0], sy: args[1], ey: args[2]}; + coord = { + x: args[0], + sy: args[1], + ey: args[2] + }; break; case 'col': - coord = {y: args[0], sx: args[1], ex: args[2]}; + coord = { + y: args[0], + sx: args[1], + ex: args[2] + }; break; case 'set': - coord = {coords: args[0]}; + coord = { + coords: args[0] + }; break; default: if (args[2] === undefined && args[3] === undefined) { - coord = {x: args[0], y: args[1]}; + coord = { + x: args[0], + y: args[1] + }; } else { - coord = {sx: args[0], sy: args[1], ex: args[2], ey: args[3]}; + coord = { + sx: args[0], + sy: args[1], + ex: args[2], + ey: args[3] + }; } } - var step = {type: type}; + var step = { + type: type + }; $.extend(step, coord); this.pushStep(step, type == 'select'); }; -Array2DTracer.prototype.processStep = function (step, options) { +Array2DTracer.prototype.processStep = function(step, options) { switch (step.type) { case 'notifying': var $row = $table.find('.mtbl-row').eq(step.x); @@ -154,7 +200,7 @@ Array2DTracer.prototype.processStep = function (step, options) { var colorClass = step.type == 'select' || step.type == 'deselect' ? tableColorClass.selected : tableColorClass.notifying; var addClass = step.type == 'select' || step.type == 'notifying'; if (step.coords) { - step.coords.forEach(function (coord) { + step.coords.forEach(function(coord) { var x = coord.x; var y = coord.y; paintColor(x, y, x, y, colorClass, addClass); @@ -174,7 +220,7 @@ Array2DTracer.prototype.processStep = function (step, options) { } }; -Array2DTracer.prototype.getCellCss = function () { +Array2DTracer.prototype.getCellCss = function() { return { padding: this.paddingV.toFixed(1) + 'px ' + this.paddingH.toFixed(1) + 'px', 'font-size': this.fontSize.toFixed(1) + 'px' @@ -182,7 +228,7 @@ Array2DTracer.prototype.getCellCss = function () { }; // Override -Array2DTracer.prototype.refresh = function () { +Array2DTracer.prototype.refresh = function() { Tracer.prototype.refresh.call(this); var $parent = $table.parent(); @@ -193,7 +239,7 @@ Array2DTracer.prototype.refresh = function () { }; // Override -Array2DTracer.prototype.prevStep = function () { +Array2DTracer.prototype.prevStep = function() { this.clear(); $('#tab_trace .wrapper').empty(); var finalIndex = this.traceIndex - 1; @@ -202,13 +248,15 @@ Array2DTracer.prototype.prevStep = function () { return; } for (var i = 0; i < finalIndex; i++) { - this.step(i, {virtual: true}); + this.step(i, { + virtual: true + }); } this.step(finalIndex); }; // Override -Array2DTracer.prototype.mousedown = function (e) { +Array2DTracer.prototype.mousedown = function(e) { Tracer.prototype.mousedown.call(this, e); this.dragX = e.pageX; @@ -217,7 +265,7 @@ Array2DTracer.prototype.mousedown = function (e) { }; // Override -Array2DTracer.prototype.mousemove = function (e) { +Array2DTracer.prototype.mousemove = function(e) { Tracer.prototype.mousemove.call(this, e); if (this.dragging) { @@ -230,14 +278,14 @@ Array2DTracer.prototype.mousemove = function (e) { }; // Override -Array2DTracer.prototype.mouseup = function (e) { +Array2DTracer.prototype.mouseup = function(e) { Tracer.prototype.mouseup.call(this, e); this.dragging = false; }; // Override -Array2DTracer.prototype.mousewheel = function (e) { +Array2DTracer.prototype.mousewheel = function(e) { Tracer.prototype.mousewheel.call(this, e); e.preventDefault(); @@ -255,12 +303,12 @@ Array2DTracer.prototype.mousewheel = function (e) { this.refresh(); }; -var initTable = function () { +var initTable = function() { $table = $('
'); $module_container.append($table); }; -var paintColor = function (sx, sy, ex, ey, colorClass, addClass) { +var paintColor = function(sx, sy, ex, ey, colorClass, addClass) { for (var i = sx; i <= ex; i++) { var $row = $table.find('.mtbl-row').eq(i); for (var j = sy; j <= ey; j++) { @@ -271,7 +319,7 @@ var paintColor = function (sx, sy, ex, ey, colorClass, addClass) { } }; -var clearTableColor = function () { +var clearTableColor = function() { $table.find('.mtbl-cell').removeClass(Object.keys(tableColorClass).join(' ')); }; From a8f90616c66f2c04763bf27f6dc3842c94bebde6 Mon Sep 17 00:00:00 2001 From: nem035 Date: Sun, 22 May 2016 00:52:01 -0400 Subject: [PATCH 2/3] Added iterative binary search algorithm --- algorithm/search/binary_search/desc.json | 3 +- .../search/binary_search/iterative/code.js | 44 +++++++++++++++++++ .../search/binary_search/iterative/data.js | 3 ++ 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 algorithm/search/binary_search/iterative/code.js create mode 100644 algorithm/search/binary_search/iterative/data.js diff --git a/algorithm/search/binary_search/desc.json b/algorithm/search/binary_search/desc.json index 6b93323c..7fe58532 100644 --- a/algorithm/search/binary_search/desc.json +++ b/algorithm/search/binary_search/desc.json @@ -12,6 +12,7 @@ "Wikipedia" ], "files": { - "recursive": "Recursively searching a sorted array" + "recursive": "Recursively searching a sorted array", + "iterative": "Iteratively searching a sorted array" } } \ No newline at end of file diff --git a/algorithm/search/binary_search/iterative/code.js b/algorithm/search/binary_search/iterative/code.js new file mode 100644 index 00000000..aa1a558a --- /dev/null +++ b/algorithm/search/binary_search/iterative/code.js @@ -0,0 +1,44 @@ +function BinarySearch(array, element) { // array = sorted array, element = element to be found, + + var minIndex = 0; + var maxIndex = array.length - 1; + var currentIndex; + var testElement; + + while (minIndex <= maxIndex) { + + middleIndex = Math.floor((minIndex + maxIndex) / 2); + testElement = array[middleIndex]; + + tracer._print('Searching at index: ' + middleIndex); + tracer._notify(middleIndex); + + if (testElement < element) { + + tracer._print('Going right.'); + minIndex = middleIndex + 1; + + } else if (testElement > element) { + + tracer._print('Going left.'); + maxIndex = middleIndex - 1; + + } else { + + tracer._print(element + ' is found at position ' + middleIndex + '!'); + tracer._select(middleIndex); + + return middleIndex; + } + } + + tracer._print(element + ' is not found!'); + return -1; +} + +var element = D[0]; + +tracer._sleep(1000); +tracer._pace(1000); +tracer._print('Using iterative binary search to find ' + element); +BinarySearch(D, element, 0, D.length - 1); \ No newline at end of file diff --git a/algorithm/search/binary_search/iterative/data.js b/algorithm/search/binary_search/iterative/data.js new file mode 100644 index 00000000..a26af590 --- /dev/null +++ b/algorithm/search/binary_search/iterative/data.js @@ -0,0 +1,3 @@ +var tracer = new Array1DTracer(); +var D = Array1D.randomSorted(15, 0, 50); +tracer._setData(D); \ No newline at end of file From 60893cd15bec8794d1bc6300422747fc0cc6d2fe Mon Sep 17 00:00:00 2001 From: nem035 Date: Sun, 22 May 2016 00:58:03 -0400 Subject: [PATCH 3/3] added base case for recursive binary search algorithm --- algorithm/search/binary_search/recursive/code.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/algorithm/search/binary_search/recursive/code.js b/algorithm/search/binary_search/recursive/code.js index db860414..2a839ff3 100644 --- a/algorithm/search/binary_search/recursive/code.js +++ b/algorithm/search/binary_search/recursive/code.js @@ -1,4 +1,9 @@ function BinarySearch(array, element, minIndex, maxIndex) { // array = sorted array, element = element to be found, minIndex = minIndex index, maxIndex = maxIndex index + if (minIndex > maxIndex) { + tracer._print(element + ' is not found!'); + return -1; + } + var middleIndex = Math.floor((minIndex + maxIndex) / 2); var testElement = array[middleIndex]; pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy