Skip to content

Commit 227bc2c

Browse files
committed
> # Welcome to the TypeScript community
> > ### Describe your change: > * [x] Add an algorithm? > * [ ] Fix a bug or typo in an existing algorithm? > * [ ] Documentation change? > > ### Checklist: > * [x] I have read [CONTRIBUTING.md](https://github.com/TheAlgorithms/Javascript/blob/master/CONTRIBUTING.md). > * [x] This pull request is all my own work -- I have not plagiarized. > * [x] I know that pull requests will not be merged if they fail the automated tests. > * [x] This PR only changes one algorithm file. To ease review, please open separate PRs for separate algorithms. > * [x] All new JavaScript files are placed inside an existing directory. > * [x] All filenames should use the UpperCamelCase (PascalCase) style. There should be no spaces in filenames. > **Example:**`UserProfile.js` is allowed but `userprofile.js`,`Userprofile.js`,`user-Profile.js`,`userProfile.js` are not > * [x] All new algorithms have a URL in its comments that points to Wikipedia or other similar explanation. > * [x] If this pull request resolves one or more open issues then the commit message contains `Fixes: #{$ISSUE_NO}`.
1 parent 292ee00 commit 227bc2c

File tree

5,672 files changed

+1640406
-0
lines changed

Some content is hidden

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

5,672 files changed

+1640406
-0
lines changed

.gitignore

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# dependencies
2+
/node_modules
3+
/temp
4+
5+
# misc
6+
.DS_Store
7+
.env.local
8+
.env.development.local
9+
.env.test.local
10+
.env.production.local
11+
12+
npm-debug.log*
13+
yarn-debug.log*
14+
yarn-error.log*
15+
16+
# intelliJ workspace folder
17+
.idea

.husky/pre-commit

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/usr/bin/env sh
2+
. "$(dirname -- "$0")/_/husky.sh"
3+
4+
npm test

Data-structures/QuickSelect.ts

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/**
2+
* [QuickSelect](https://www.geeksforgeeks.org/quickselect-algorithm/) is an algorithm to find the kth smallest number
3+
*
4+
* Notes:
5+
* - QuickSelect is related to QuickSort, thus has optimal best and average case (O(n)) but unlikely poor worst case (O(n^2))
6+
* - This implementation uses randomly selected pivots for better performance
7+
* ----
8+
* @complexity : O(n) (on average )
9+
* @complexity : O(n^2) (worst case)
10+
* ----
11+
* @param items array
12+
*/
13+
14+
const QuickSelect = (items: Array<number>, kth: number): number => {
15+
// eslint-disable-line no-unused-vars
16+
if (kth < 1 || kth > items.length) {
17+
throw new RangeError("Index Out of Bound");
18+
}
19+
20+
return RandomizedSelect(items, 0, items.length - 1, kth);
21+
};
22+
23+
/**
24+
* @param items
25+
* @param left
26+
* @param right
27+
* @param i
28+
* @returns number
29+
*/
30+
const RandomizedSelect = (
31+
items: Array<number>,
32+
left: number,
33+
right: number,
34+
i: number
35+
): number => {
36+
if (left === right) return items[left];
37+
38+
const pivotIndex = RandomizedPartition(items, left, right);
39+
const k = pivotIndex - left + 1;
40+
41+
if (i === k) return items[pivotIndex];
42+
if (i < k) return RandomizedSelect(items, left, pivotIndex - 1, i);
43+
44+
return RandomizedSelect(items, pivotIndex + 1, right, i - k);
45+
};
46+
/**
47+
*
48+
* @param items
49+
* @param left
50+
* @param right
51+
* @returns
52+
*/
53+
const RandomizedPartition = (
54+
items: Array<number>,
55+
left: number,
56+
right: number
57+
): number => {
58+
const rand = getRandomInt(left, right);
59+
Swap(items, rand, right);
60+
return Partition(items, left, right);
61+
};
62+
/**
63+
*
64+
* @param items
65+
* @param left
66+
* @param right
67+
* @returns
68+
*/
69+
const Partition = (items: Array<number>, left: number, right: number) : number => {
70+
const x = items[right];
71+
let pivotIndex = left - 1;
72+
73+
for (let j = left; j < right; j++) {
74+
if (items[j] <= x) {
75+
pivotIndex++;
76+
Swap(items, pivotIndex, j);
77+
}
78+
}
79+
80+
Swap(items, pivotIndex + 1, right);
81+
82+
return pivotIndex + 1;
83+
};
84+
85+
/**
86+
*
87+
* @param min
88+
* @param max
89+
* @returns
90+
*/
91+
const getRandomInt = (min : number, max : number) : number => {
92+
return Math.floor(Math.random() * (max - min + 1)) + min;
93+
}
94+
95+
96+
/**
97+
*
98+
* @param arr array
99+
* @param x array element to swap
100+
* @param y array element to swap
101+
*/
102+
const Swap = (arr : Array<number>, x : number, y : number) : void => {
103+
[arr[x], arr[y]] = [arr[y], arr[x]];
104+
}
105+
106+
export { QuickSelect };
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { QuickSelect } from '../QuickSelect'
2+
3+
describe('QuickSelect tests', () => {
4+
it('should return the only element of a list of length 1', () => {
5+
// Test a mix of number types (i.e., positive/negative, numbers with decimals, fractions)
6+
expect(QuickSelect([100], 1)).toEqual(100)
7+
expect(QuickSelect([-23], 1)).toEqual(-23)
8+
expect(QuickSelect([2007.102], 1)).toEqual(2007.102)
9+
expect(QuickSelect([0.9], 1)).toEqual(0.9)
10+
expect(QuickSelect([-0.075], 1)).toEqual(-0.075)
11+
expect(QuickSelect([0], 1)).toEqual(0)
12+
expect(QuickSelect([1], 1)).toEqual(1)
13+
})
14+
15+
it('should throw an Error when k is greater than the length of the list', () => {
16+
expect(() => QuickSelect([100, 2], 5)).toThrow('Index Out of Bound')
17+
})
18+
19+
it('should throw an Error when k is less than 1', () => {
20+
expect(() => QuickSelect([100, 2], 0)).toThrow('Index Out of Bound')
21+
expect(() => QuickSelect([100, 2], -1)).toThrow('Index Out of Bound')
22+
})
23+
24+
describe('varieties of list composition', () => {
25+
it('should return the kth smallest element of a list that is in increasing order', () => {
26+
expect(QuickSelect([10, 22, 33, 44, 55], 1)).toEqual(10)
27+
expect(QuickSelect([10, 22, 33, 44, 55], 2)).toEqual(22)
28+
expect(QuickSelect([10, 22, 33, 44, 55], 3)).toEqual(33)
29+
expect(QuickSelect([10, 22, 33, 44, 55], 4)).toEqual(44)
30+
expect(QuickSelect([10, 22, 33, 44, 55], 5)).toEqual(55)
31+
})
32+
33+
it('should return the kth smallest element of an input list that is in decreasing order', () => {
34+
expect(QuickSelect([82, 33.12, 4.0, 1], 1)).toEqual(1)
35+
expect(QuickSelect([82, 33.12, 4.0, 1], 2)).toEqual(4.0)
36+
expect(QuickSelect([82, 33.12, 4.0, 1], 2)).toEqual(4)
37+
expect(QuickSelect([82, 33.12, 4.0, 1], 3)).toEqual(33.12)
38+
expect(QuickSelect([82, 33.12, 4.0, 1], 4)).toEqual(82)
39+
})
40+
41+
it('should return the kth smallest element of an input list that is no particular order', () => {
42+
expect(QuickSelect([123, 14231, -10, 0, 15], 3)).toEqual(15)
43+
expect(QuickSelect([0, 15, 123, 14231, -10], 3)).toEqual(15)
44+
expect(QuickSelect([-10, 15, 123, 14231, 0], 3)).toEqual(15)
45+
expect(QuickSelect([14231, 0, 15, 123, -10], 3)).toEqual(15)
46+
expect(QuickSelect([14231, 0, 15, -10, 123], 3)).toEqual(15)
47+
})
48+
})
49+
})

babel.config.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module.exports = {
2+
presets: [
3+
['@babel/preset-env', { targets: { node: 'current' } }],
4+
'@babel/preset-typescript'],
5+
6+
};

jest.config.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import type { Config } from "@jest/types";
2+
// Sync object
3+
const config: Config.InitialOptions = {
4+
verbose: true,
5+
transform: {
6+
"^.+\\.tsx?$": "ts-jest",
7+
},
8+
};
9+
export default config;

node_modules/.bin/acorn

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/browserslist

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/browserslist-lint

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/esparse

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/esvalidate

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/husky

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/import-local-fixture

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/jest

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/js-yaml

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/jsesc

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/json5

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/node-which

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/parser

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/regjsparser

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/resolve

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/semver

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/ts-jest

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/ts-node

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/ts-node-cwd

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/ts-node-esm

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/ts-node-script

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/ts-node-transpile-only

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/ts-script

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/tsc

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/tsserver

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)