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..7fe58532 --- /dev/null +++ b/algorithm/search/binary_search/desc.json @@ -0,0 +1,18 @@ +{ + "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", + "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 diff --git a/algorithm/search/binary_search/recursive/code.js b/algorithm/search/binary_search/recursive/code.js new file mode 100644 index 00000000..2a839ff3 --- /dev/null +++ b/algorithm/search/binary_search/recursive/code.js @@ -0,0 +1,38 @@ +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]; + + 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(' ')); }; 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