Skip to content

Commit 56a4153

Browse files
committed
Sorting and Searching Algorithms
1 parent 9607ab5 commit 56a4153

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+909
-13
lines changed

.vscode/launch.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,9 @@
4141
"-r",
4242
"ts-node/register",
4343
"--colors",
44-
"${workspaceRoot}/test/ts/**/*.spec.ts"
44+
"${workspaceRoot}/test/ts/**/**/*.spec.ts"
4545
],
46+
"protocol": "auto",
4647
"internalConsoleOptions": "openOnSessionStart"
4748
}
4849
]

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Work in Progress.
2121
* 09: [Trees](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter09)
2222
* 10: [Heap](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter10)
2323
* 11: [Graphs](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter11)
24+
* 12: [Sorting and Searching Algorithms](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter12)
2425

2526
### Third Edition Updates
2627

package.json

+11-11
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
"lint:js": "eslint src/js && eslint test/js",
2222
"lint:ts": "tslint -c tslint.json 'src/ts/**/*.ts' && tslint -c tslint.json 'test/ts/**/*.ts'",
2323
"lint": "npm run lint:js && npm run lint:ts",
24-
"test:js": "mocha --compilers js:babel-core/register ./test/js/**/*.spec.js --reporter mochawesome",
25-
"test:ts": "mocha -r ts-node/register --recursive ./test/ts/**/*.spec.ts",
24+
"test:js": "mocha --compilers js:babel-core/register ./test/js/**/**/*.spec.js --reporter mochawesome",
25+
"test:ts": "mocha -r ts-node/register --recursive ./test/ts/**/**/*.spec.ts",
2626
"test": "npm run test:js && npm run test:ts",
2727
"dev": "npm run clean && npm run lint && npm run webpack && npm run generate-report",
2828
"dev2": "npm run clean && npm run lint && npm run webpack && npm run generate-report2",
@@ -53,28 +53,28 @@
5353
"all": true
5454
},
5555
"devDependencies": {
56-
"@types/chai": "^4.0.4",
57-
"@types/mocha": "^2.2.44",
56+
"@types/chai": "^4.0.10",
57+
"@types/mocha": "^2.2.45",
5858
"babel-cli": "^6.26.0",
5959
"babel-core": "^6.26.0",
60-
"babel-eslint": "^8.0.1",
60+
"babel-eslint": "^8.1.0",
6161
"babel-loader": "^7.1.2",
6262
"babel-plugin-add-module-exports": "^0.2.1",
6363
"babel-plugin-transform-es2015-modules-umd": "^6.24.1",
6464
"babel-preset-env": "^1.6.1",
6565
"chai": "^4.1.2",
6666
"codecov": "^3.0.0",
67-
"eslint": "^4.10.0",
67+
"eslint": "^4.14.0",
6868
"eslint-config-airbnb-base": "^12.1.0",
6969
"eslint-plugin-import": "^2.8.0",
7070
"istanbul": "^v1.1.0-alpha.1",
7171
"mocha": "^4.0.1",
72-
"mochawesome": "^2.3.1",
73-
"nyc": "^11.2.1",
74-
"ts-node": "^3.3.0",
72+
"mochawesome": "^3.0.0",
73+
"nyc": "^11.4.1",
74+
"ts-node": "^4.1.0",
7575
"tslint": "^5.8.0",
76-
"typescript": "^2.5.3",
77-
"webpack": "^3.8.1",
76+
"typescript": "^2.6.2",
77+
"webpack": "^3.10.0",
7878
"yargs": "^10.0.3"
7979
}
8080
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { Compare, defaultCompare, swap } from '../../util';
2+
3+
export function modifiedBubbleSort(array, compareFn = defaultCompare) {
4+
const { length } = array;
5+
for (let i = 0; i < length; i++) {
6+
// console.log('--- ');
7+
for (let j = 0; j < length - 1 - i; j++) {
8+
// console.log('compare ' + array[j] + ' with ' + array[j + 1]);
9+
if (compareFn(array[j], array[j + 1]) === Compare.BIGGER_THAN) {
10+
// console.log('swap ' + array[j] + ' with ' + array[j + 1]);
11+
swap(array, j, j + 1);
12+
}
13+
}
14+
}
15+
return array;
16+
}
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { Compare, defaultCompare, swap } from '../../util';
2+
3+
export function bubbleSort(array, compareFn = defaultCompare) {
4+
const { length } = array;
5+
for (let i = 0; i < length; i++) {
6+
// console.log('--- ');
7+
for (let j = 0; j < length - 1; j++) {
8+
// console.log('compare ' + array[j] + ' with ' + array[j + 1]);
9+
if (compareFn(array[j], array[j + 1]) === Compare.BIGGER_THAN) {
10+
// console.log('swap ' + array[j] + ' with ' + array[j + 1]);
11+
swap(array, j, j + 1);
12+
}
13+
}
14+
}
15+
return array;
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { Compare, defaultCompare } from '../../util';
2+
3+
export const insertionSort = (array, compareFn = defaultCompare) => {
4+
const { length } = array;
5+
let temp;
6+
for (let i = 1; i < length; i++) {
7+
let j = i;
8+
temp = array[i];
9+
// console.log('to be inserted ' + temp);
10+
while (j > 0 && compareFn(array[j - 1], temp) === Compare.BIGGER_THAN) {
11+
// console.log('shift ' + array[j - 1]);
12+
array[j] = array[j - 1];
13+
j--;
14+
}
15+
// console.log('insert ' + temp);
16+
array[j] = temp;
17+
}
18+
return array;
19+
};
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { Compare, defaultCompare } from '../../util';
2+
3+
function merge(left, right, compareFn) {
4+
let i = 0;
5+
let j = 0;
6+
const result = [];
7+
while (i < left.length && j < right.length) {
8+
result.push(compareFn(left[i], right[j]) === Compare.LESS_THAN ? left[i++] : right[j++]);
9+
}
10+
return result.concat(i < left.length ? left.slice(i) : right.slice(j));
11+
}
12+
export function mergeSort(array, compareFn = defaultCompare) {
13+
if (array.length > 1) {
14+
const { length } = array;
15+
const middle = Math.floor(length / 2);
16+
const left = mergeSort(array.slice(0, middle), compareFn);
17+
const right = mergeSort(array.slice(middle, length), compareFn);
18+
array = merge(left, right, compareFn);
19+
}
20+
return array;
21+
}
+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { Compare, defaultCompare, swap } from '../../util';
2+
3+
function partition(array, left, right, compareFn) {
4+
const pivot = array[Math.floor((right + left) / 2)];
5+
let i = left;
6+
let j = right;
7+
// console.log('pivot is ' + pivot + '; left is ' + left + '; right is ' + right);
8+
while (i <= j) {
9+
while (compareFn(array[i], pivot) === Compare.LESS_THAN) {
10+
i++;
11+
// console.log('i = ' + i);
12+
}
13+
while (compareFn(array[j], pivot) === Compare.BIGGER_THAN) {
14+
j--;
15+
// console.log('j = ' + j);
16+
}
17+
if (i <= j) {
18+
// console.log('swap ' + array[i] + ' with ' + array[j]);
19+
swap(array, i, j);
20+
i++;
21+
j--;
22+
}
23+
}
24+
return i;
25+
}
26+
function quick(array, left, right, compareFn) {
27+
let index;
28+
if (array.length > 1) {
29+
index = partition(array, left, right, compareFn);
30+
if (left < index - 1) {
31+
quick(array, left, index - 1, compareFn);
32+
}
33+
if (index < right) {
34+
quick(array, index, right, compareFn);
35+
}
36+
}
37+
return array;
38+
}
39+
export function quickSort(array, compareFn = defaultCompare) {
40+
return quick(array, 0, array.length - 1, compareFn);
41+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { Compare, defaultCompare, swap } from '../../util';
2+
3+
export const selectionSort = (array, compareFn = defaultCompare) => {
4+
const { length } = array;
5+
let indexMin;
6+
for (let i = 0; i < length - 1; i++) {
7+
indexMin = i;
8+
// console.log('index ' + array[i]);
9+
for (let j = i; j < length; j++) {
10+
if (compareFn(array[indexMin], array[j]) === Compare.BIGGER_THAN) {
11+
// console.log('new index min ' + array[j]);
12+
indexMin = j;
13+
}
14+
}
15+
if (i !== indexMin) {
16+
// console.log('swap ' + array[i] + ' with ' + array[indexMin]);
17+
swap(array, i, indexMin);
18+
}
19+
}
20+
return array;
21+
};
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { Compare, defaultCompare } from '../../util';
2+
3+
export function shellSort(array, compareFn = defaultCompare) {
4+
let increment = array.length / 2;
5+
while (increment > 0) {
6+
for (let i = increment; i < array.length; i++) {
7+
let j = i;
8+
const temp = array[i];
9+
while (j >= increment && compareFn(array[j - increment], temp) === Compare.BIGGER_THAN) {
10+
array[j] = array[j - increment];
11+
j -= increment;
12+
}
13+
array[j] = temp;
14+
}
15+
if (increment === 2) {
16+
increment = 1;
17+
} else {
18+
increment = Math.floor((increment * 5) / 11);
19+
}
20+
}
21+
return array;
22+
}
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { Compare, defaultCompare, DOES_NOT_EXIST } from '../../util';
2+
import { quickSort } from '../sorting/quicksort';
3+
4+
export function binarySearch<T> (array: T[], value: T, compareFn = defaultCompare) {
5+
const sortedArray = quickSort(array);
6+
let low = 0;
7+
let high = sortedArray.length - 1;
8+
9+
while (low <= high) {
10+
const mid = Math.floor((low + high) / 2);
11+
const element = sortedArray[mid];
12+
// console.log('mid element is ' + element);
13+
if (compareFn(element, value) === Compare.LESS_THAN) {
14+
low = mid + 1;
15+
// console.log('low is ' + low);
16+
} else if (compareFn(element, value) === Compare.BIGGER_THAN) {
17+
high = mid - 1;
18+
// console.log('high is ' + high);
19+
} else {
20+
// console.log('found it');
21+
return mid;
22+
}
23+
}
24+
return DOES_NOT_EXIST;
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import {
2+
biggerEquals,
3+
Compare,
4+
defaultCompare,
5+
defaultEquals,
6+
defaultDiff,
7+
DOES_NOT_EXIST,
8+
lesserEquals
9+
} from '../../util';
10+
11+
export function interpolationSearch<T>(
12+
array: T[],
13+
value: T,
14+
compareFn = defaultCompare,
15+
equalsFn = defaultEquals,
16+
diffFn = defaultDiff
17+
) {
18+
const { length } = array;
19+
let low = 0;
20+
let high = length - 1;
21+
let position = -1;
22+
let delta = -1;
23+
while (
24+
low <= high &&
25+
biggerEquals(value, array[low], compareFn) &&
26+
lesserEquals(value, array[high], compareFn)
27+
) {
28+
delta = diffFn(value, array[low]) / diffFn(array[high], array[low]);
29+
position = low + Math.floor((high - low) * delta);
30+
if (equalsFn(array[position], value)) {
31+
return position;
32+
}
33+
if (compareFn(array[position], value) === Compare.LESS_THAN) {
34+
low = position + 1;
35+
} else {
36+
high = position - 1;
37+
}
38+
}
39+
40+
return DOES_NOT_EXIST;
41+
}
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { defaultCompare, Compare } from '../../util';
2+
3+
export function findMaxValue<T>(array: T[], compareFn = defaultCompare) {
4+
if (array && array.length > 0) {
5+
let max = array[0];
6+
for (let i = 1; i < array.length; i++) {
7+
if (compareFn(max, array[i]) === Compare.LESS_THAN) {
8+
max = array[i];
9+
}
10+
}
11+
return max;
12+
}
13+
return undefined;
14+
}
15+
16+
export function findMinValue<T>(array: T[], compareFn = defaultCompare) {
17+
if (array && array.length > 0) {
18+
let min = array[0];
19+
for (let i = 1; i < array.length; i++) {
20+
if (compareFn(min, array[i]) === Compare.BIGGER_THAN) {
21+
min = array[i];
22+
}
23+
}
24+
return min;
25+
}
26+
return undefined;
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { defaultEquals, DOES_NOT_EXIST, IEqualsFunction } from '../../util';
2+
3+
export function sequentialSearch<T>(array: T[], value: T, equalsFn: IEqualsFunction<T> = defaultEquals) {
4+
for (let i = 0; i < array.length; i++) {
5+
if (equalsFn(value, array[i])) {
6+
return i;
7+
}
8+
}
9+
return DOES_NOT_EXIST;
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { swap } from '../../util';
2+
3+
export function shuffle<T>(array: T[]) {
4+
let currentIndex = array.length;
5+
6+
while (currentIndex !== 0) {
7+
const randomIndex = Math.floor(Math.random() * currentIndex);
8+
currentIndex--;
9+
swap(array, currentIndex, randomIndex);
10+
}
11+
12+
return array;
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Compare, defaultCompare, swap } from '../../util';
2+
3+
export function modifiedBubbleSort<T>(array: T[], compareFn = defaultCompare) {
4+
const { length } = array;
5+
6+
for (let i = 0; i < length; i++) {
7+
// console.log('--- ');
8+
for (let j = 0; j < length - 1 - i; j++) {
9+
// console.log('compare ' + array[j] + ' with ' + array[j + 1]);
10+
if (compareFn(array[j], array[j + 1]) === Compare.BIGGER_THAN) {
11+
// console.log('swap ' + array[j] + ' with ' + array[j + 1]);
12+
swap(array, j, j + 1);
13+
}
14+
}
15+
}
16+
17+
return array;
18+
}
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Compare, defaultCompare, swap } from '../../util';
2+
3+
export function bubbleSort<T>(array: T[], compareFn = defaultCompare) {
4+
const { length } = array;
5+
6+
for (let i = 0; i < length; i++) {
7+
// console.log('--- ');
8+
for (let j = 0; j < length - 1; j++) {
9+
// console.log('compare ' + array[j] + ' with ' + array[j + 1]);
10+
if (compareFn(array[j], array[j + 1]) === Compare.BIGGER_THAN) {
11+
// console.log('swap ' + array[j] + ' with ' + array[j + 1]);
12+
swap(array, j, j + 1);
13+
}
14+
}
15+
}
16+
17+
return array;
18+
}

0 commit comments

Comments
 (0)