sort-n-search 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +1 -3
- package/package.json +1 -1
- package/src/factory/AlgorithmFactory.js +47 -0
- package/src/searching/BinarySearch.js +34 -0
- package/src/searching/LinearSearch.js +25 -0
- package/src/searching/SearchStrategy.js +5 -0
- package/src/sorting/BubbleSort.js +30 -0
- package/src/sorting/InsertSort.js +26 -0
- package/src/sorting/MergeSort.js +41 -0
- package/src/sorting/QuickSort.js +25 -0
- package/src/sorting/SelectSort.js +32 -0
- package/src/sorting/SortStrategy.js +5 -0
- package/src/tests/searching/BinarySearch.test.js +25 -0
- package/src/tests/searching/LinearSearch.test.js +25 -0
- package/src/tests/sorting/BubbleSort.test.js +24 -0
- package/src/tests/sorting/InsertSort.test.js +24 -0
- package/src/tests/sorting/MergeSort.test.js +24 -0
- package/src/tests/sorting/QuickSort.test.js +24 -0
- package/src/tests/sorting/SelectSort.test.js +24 -0
- package/src/searching/binarySearch.js +0 -30
- package/src/searching/index.js +0 -2
- package/src/searching/linearSearch.js +0 -21
- package/src/sorting/bubbleSort.js +0 -25
- package/src/sorting/index.js +0 -3
- package/src/sorting/mergeSort.js +0 -37
- package/src/sorting/quickSort.js +0 -21
- package/src/tests/searching/binarySearch.test.js +0 -17
- package/src/tests/searching/linearSearch.test.js +0 -17
- package/src/tests/sorting/bubbleSort.test.js +0 -21
- package/src/tests/sorting/mergeSort.test.js +0 -21
- package/src/tests/sorting/quickSort.test.js +0 -21
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { BubbleSort } from "../sorting/BubbleSort.js";
|
|
2
|
+
import { InsertSort } from "../sorting/InsertSort.js";
|
|
3
|
+
import { MergeSort } from "../sorting/MergeSort.js";
|
|
4
|
+
import { QuickSort } from "../sorting/QuickSort.js";
|
|
5
|
+
import { SelectSort } from "../sorting/SelectSort.js";
|
|
6
|
+
import { LinearSearch } from "../searching/LinearSearch.js";
|
|
7
|
+
import { BinarySearch } from "../searching/BinarySearch.js";
|
|
8
|
+
|
|
9
|
+
export class AlgorithmFactory {
|
|
10
|
+
|
|
11
|
+
static getSorter(type) {
|
|
12
|
+
|
|
13
|
+
switch (type) {
|
|
14
|
+
case "bubble":
|
|
15
|
+
return new BubbleSort();
|
|
16
|
+
|
|
17
|
+
case "insert":
|
|
18
|
+
return new InsertSort();
|
|
19
|
+
|
|
20
|
+
case "merge":
|
|
21
|
+
return new MergeSort();
|
|
22
|
+
|
|
23
|
+
case "quick":
|
|
24
|
+
return new QuickSort();
|
|
25
|
+
|
|
26
|
+
case "select":
|
|
27
|
+
return new SelectSort();
|
|
28
|
+
|
|
29
|
+
default:
|
|
30
|
+
throw new Error("Неизвестный алгоритм сортировки");
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
static getSearcher(type) {
|
|
35
|
+
|
|
36
|
+
switch (type) {
|
|
37
|
+
case "linear":
|
|
38
|
+
return new LinearSearch();
|
|
39
|
+
|
|
40
|
+
case "binary":
|
|
41
|
+
return new BinarySearch();
|
|
42
|
+
|
|
43
|
+
default:
|
|
44
|
+
throw new Error("Неизвестный алгоритм поиска");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { SearchStrategy } from "./SearchStrategy";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Бинарный поиск (для отсортированных массивов)
|
|
5
|
+
* @param {number[]} array - отсортированный массив
|
|
6
|
+
* @param {number} target - целевое значение
|
|
7
|
+
* @returns {number} - индекс элемента или -1 если не найдено
|
|
8
|
+
* @time O(log n)
|
|
9
|
+
* @space O(1)
|
|
10
|
+
*/
|
|
11
|
+
export class BinarySearch extends SearchStrategy {
|
|
12
|
+
search(array, target) {
|
|
13
|
+
if (!Array.isArray(array)) {
|
|
14
|
+
throw new Error('Input must be an array');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let left = 0;
|
|
18
|
+
let right = array.length - 1;
|
|
19
|
+
|
|
20
|
+
while (left <= right) {
|
|
21
|
+
const mid = Math.floor((left + right) / 2);
|
|
22
|
+
|
|
23
|
+
if (array[mid] === target) {
|
|
24
|
+
return mid;
|
|
25
|
+
} else if (array[mid] < target) {
|
|
26
|
+
left = mid + 1;
|
|
27
|
+
} else {
|
|
28
|
+
right = mid - 1;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return -1;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { SearchStrategy } from "./SearchStrategy";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Линейный поиск
|
|
5
|
+
* @param {number[]} array - массив для поиска
|
|
6
|
+
* @param {number} target - целевое значение
|
|
7
|
+
* @returns {number} - индекс элемента или -1 если не найдено
|
|
8
|
+
* @time O(n)
|
|
9
|
+
* @space O(1)
|
|
10
|
+
*/
|
|
11
|
+
export class LinearSearch extends SearchStrategy {
|
|
12
|
+
search(array, target) {
|
|
13
|
+
if (!Array.isArray(array)) {
|
|
14
|
+
throw new Error('Input must be an array');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
for (let i = 0; i < array.length; i++) {
|
|
18
|
+
if (array[i] === target) {
|
|
19
|
+
return i;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return -1;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Сортировка пузырьком
|
|
3
|
+
* @param {number[]} array - массив для сортировки
|
|
4
|
+
* @returns {number[]} - отсортированный массив
|
|
5
|
+
* @time O(n²)
|
|
6
|
+
* @space O(1)
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { SortStrategy } from "./SortStrategy"
|
|
10
|
+
|
|
11
|
+
export class BubbleSort extends SortStrategy {
|
|
12
|
+
sort(array) {
|
|
13
|
+
if (!Array.isArray(array)) {
|
|
14
|
+
throw new Error('Input must be an array');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const result = [...array];
|
|
18
|
+
const n = result.length;
|
|
19
|
+
|
|
20
|
+
for (let i = 0; i < n - 1; i++) {
|
|
21
|
+
for (let j = 0; j < n - i - 1; j++) {
|
|
22
|
+
if (result[j] > result[j + 1]) {
|
|
23
|
+
[result[j], result[j + 1]] = [result[j + 1], result[j]];
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { SortStrategy } from "./SortStrategy";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Сортировка вставками
|
|
5
|
+
* @param {number[]} array - массив для сортировки
|
|
6
|
+
* @returns {number[]} - отсортированный массив
|
|
7
|
+
* @time O(n) в лучшем случае, O(n²) в среднем и худшем
|
|
8
|
+
* @space O(1)
|
|
9
|
+
*/
|
|
10
|
+
export class InsertSort extends SortStrategy {
|
|
11
|
+
sort(array) {
|
|
12
|
+
for (let i = 1; i < array.length; i++) {
|
|
13
|
+
const current = array[i];
|
|
14
|
+
let j = i - 1;
|
|
15
|
+
|
|
16
|
+
while (j >= 0 && array[j] > current) {
|
|
17
|
+
array[j + 1] = array[j];
|
|
18
|
+
j--;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
array[j + 1] = current;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return array;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { SortStrategy } from "./SortStrategy";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Сортировка слиянием
|
|
5
|
+
* @param {number[]} array - массив для сортировки
|
|
6
|
+
* @returns {number[]} - отсортированный массив
|
|
7
|
+
* @time O(n log n)
|
|
8
|
+
* @space O(n)
|
|
9
|
+
*/
|
|
10
|
+
export class MergeSort extends SortStrategy {
|
|
11
|
+
merge(left, right) {
|
|
12
|
+
const result = [];
|
|
13
|
+
let i = 0, j = 0;
|
|
14
|
+
|
|
15
|
+
while (i < left.length && j < right.length) {
|
|
16
|
+
if (left[i] <= right[j]) {
|
|
17
|
+
result.push(left[i]);
|
|
18
|
+
i++;
|
|
19
|
+
} else {
|
|
20
|
+
result.push(right[j]);
|
|
21
|
+
j++;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return [...result, ...left.slice(i), ...right.slice(j)];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
sort(array) {
|
|
29
|
+
if (!Array.isArray(array)) {
|
|
30
|
+
throw new Error('Input must be an array');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (array.length <= 1) return array;
|
|
34
|
+
|
|
35
|
+
const mid = Math.floor(array.length / 2);
|
|
36
|
+
const left = this.sort(array.slice(0, mid));
|
|
37
|
+
const right = this.sort(array.slice(mid));
|
|
38
|
+
|
|
39
|
+
return this.merge(left, right);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { SortStrategy } from "./SortStrategy";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Быстрая сортировка
|
|
5
|
+
* @param {number[]} array - массив для сортировки
|
|
6
|
+
* @returns {number[]} - отсортированный массив
|
|
7
|
+
* @time O(n log n) в среднем, O(n²) в худшем
|
|
8
|
+
* @space O(log n)
|
|
9
|
+
*/
|
|
10
|
+
export class QuickSort extends SortStrategy {
|
|
11
|
+
sort(array) {
|
|
12
|
+
if (!Array.isArray(array)) {
|
|
13
|
+
throw new Error('Input must be an array');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (array.length <= 1) return array;
|
|
17
|
+
|
|
18
|
+
const pivot = array[Math.floor(array.length / 2)];
|
|
19
|
+
const left = array.filter(x => x < pivot);
|
|
20
|
+
const middle = array.filter(x => x === pivot);
|
|
21
|
+
const right = array.filter(x => x > pivot);
|
|
22
|
+
|
|
23
|
+
return [...this.sort(left), ...middle, ...this.sort(right)];
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { SortStrategy } from "./SortStrategy";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Сортировка выбором
|
|
5
|
+
* @param {number[]} array - массив для сортировки
|
|
6
|
+
* @returns {number[]} - отсортированный массив
|
|
7
|
+
* @time O(n²) в лучшем, среднем и худшем случае
|
|
8
|
+
* @space O(1)
|
|
9
|
+
*/
|
|
10
|
+
export class SelectSort extends SortStrategy {
|
|
11
|
+
sort(array) {
|
|
12
|
+
if (!Array.isArray(array)) {
|
|
13
|
+
throw new Error('Input must be an array');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
for (let i = 0; i < array.length - 1; i++) {
|
|
17
|
+
let minIndex = i;
|
|
18
|
+
|
|
19
|
+
for (let j = i + 1; j < array.length; j++) {
|
|
20
|
+
if (array[j] < array[minIndex]) {
|
|
21
|
+
minIndex = j;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (minIndex !== i) {
|
|
26
|
+
[array[i], array[minIndex]] = [array[minIndex], array[i]];
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return array;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { BinarySearch } from "../../searching/BinarySearch"
|
|
2
|
+
|
|
3
|
+
describe('BinarySearch', () => {
|
|
4
|
+
let searcher;
|
|
5
|
+
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
searcher = new BinarySearch();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
test('находит элемент в отсортированном массиве', () => {
|
|
11
|
+
const array = [1, 3, 5, 7, 9, 11];
|
|
12
|
+
|
|
13
|
+
expect(searcher.search(array, 7)).toBe(3);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test('возвращает -1 если элемент не найден', () => {
|
|
17
|
+
const array = [1, 3, 5, 7, 9];
|
|
18
|
+
|
|
19
|
+
expect(searcher.search(array, 6)).toBe(-1);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test('обрабатывает пустой массив', () => {
|
|
23
|
+
expect(searcher.search([], 5)).toBe(-1);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { LinearSearch } from "../../searching/LinearSearch"
|
|
2
|
+
|
|
3
|
+
describe('LinearSearch', () => {
|
|
4
|
+
let searcher;
|
|
5
|
+
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
searcher = new LinearSearch();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
test('находит элемент в массиве', () => {
|
|
11
|
+
const array = [1, 3, 5, 7, 9, 11];
|
|
12
|
+
|
|
13
|
+
expect(searcher.search(array, 7)).toBe(3);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test('возвращает -1 если элемент не найден', () => {
|
|
17
|
+
const array = [1, 3, 5, 7, 9];
|
|
18
|
+
|
|
19
|
+
expect(searcher.search(array, 6)).toBe(-1);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test('обрабатывает пустой массив', () => {
|
|
23
|
+
expect(searcher.search([], 5)).toBe(-1);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { BubbleSort } from "../../sorting/BubbleSort"
|
|
2
|
+
|
|
3
|
+
describe('BubbleSort', () => {
|
|
4
|
+
let sorter;
|
|
5
|
+
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
sorter = new BubbleSort();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
test('сортирует массив чисел правильно', () => {
|
|
11
|
+
const input = [5, 2, 8, 1, 9];
|
|
12
|
+
const expected = [1, 2, 5, 8, 9];
|
|
13
|
+
|
|
14
|
+
expect(sorter.sort(input)).toEqual(expected);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test('возвращает пустой массив для пустого входного', () => {
|
|
18
|
+
expect(sorter.sort([])).toEqual([]);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('обрабатывает массив с одним элементом', () => {
|
|
22
|
+
expect(sorter.sort([42])).toEqual([42]);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { InsertSort } from "../../sorting/InsertSort"
|
|
2
|
+
|
|
3
|
+
describe('InsertSort', () => {
|
|
4
|
+
let sorter;
|
|
5
|
+
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
sorter = new InsertSort();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
test('сортирует массив чисел правильно', () => {
|
|
11
|
+
const input = [5, 2, 8, 1, 9];
|
|
12
|
+
const expected = [1, 2, 5, 8, 9];
|
|
13
|
+
|
|
14
|
+
expect(sorter.sort(input)).toEqual(expected);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test('возвращает пустой массив для пустого входного', () => {
|
|
18
|
+
expect(sorter.sort([])).toEqual([]);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('обрабатывает массив с одним элементом', () => {
|
|
22
|
+
expect(sorter.sort([42])).toEqual([42]);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { MergeSort } from "../../sorting/MergeSort"
|
|
2
|
+
|
|
3
|
+
describe('MergeSort', () => {
|
|
4
|
+
let sorter;
|
|
5
|
+
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
sorter = new MergeSort();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
test('сортирует массив чисел правильно', () => {
|
|
11
|
+
const input = [5, 2, 8, 1, 9];
|
|
12
|
+
const expected = [1, 2, 5, 8, 9];
|
|
13
|
+
|
|
14
|
+
expect(sorter.sort(input)).toEqual(expected);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test('возвращает пустой массив для пустого входного', () => {
|
|
18
|
+
expect(sorter.sort([])).toEqual([]);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('обрабатывает массив с одним элементом', () => {
|
|
22
|
+
expect(sorter.sort([42])).toEqual([42]);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { QuickSort } from "../../sorting/QuickSort"
|
|
2
|
+
|
|
3
|
+
describe('QuickSort', () => {
|
|
4
|
+
let sorter;
|
|
5
|
+
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
sorter = new QuickSort();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
test('сортирует массив чисел правильно', () => {
|
|
11
|
+
const input = [5, 2, 8, 1, 9];
|
|
12
|
+
const expected = [1, 2, 5, 8, 9];
|
|
13
|
+
|
|
14
|
+
expect(sorter.sort(input)).toEqual(expected);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test('возвращает пустой массив для пустого входного', () => {
|
|
18
|
+
expect(sorter.sort([])).toEqual([]);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('обрабатывает массив с одним элементом', () => {
|
|
22
|
+
expect(sorter.sort([42])).toEqual([42]);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { SelectSort } from "../../sorting/SelectSort"
|
|
2
|
+
|
|
3
|
+
describe('SelectSort', () => {
|
|
4
|
+
let sorter;
|
|
5
|
+
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
sorter = new SelectSort();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
test('сортирует массив чисел правильно', () => {
|
|
11
|
+
const input = [5, 2, 8, 1, 9];
|
|
12
|
+
const expected = [1, 2, 5, 8, 9];
|
|
13
|
+
|
|
14
|
+
expect(sorter.sort(input)).toEqual(expected);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test('возвращает пустой массив для пустого входного', () => {
|
|
18
|
+
expect(sorter.sort([])).toEqual([]);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('обрабатывает массив с одним элементом', () => {
|
|
22
|
+
expect(sorter.sort([42])).toEqual([42]);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Бинарный поиск (для отсортированных массивов)
|
|
3
|
-
* @param {number[]} array - отсортированный массив
|
|
4
|
-
* @param {number} target - целевое значение
|
|
5
|
-
* @returns {number} - индекс элемента или -1 если не найдено
|
|
6
|
-
* @time O(log n)
|
|
7
|
-
* @space O(1)
|
|
8
|
-
*/
|
|
9
|
-
export function binarySearch(array, target) {
|
|
10
|
-
if (!Array.isArray(array)) {
|
|
11
|
-
throw new Error('Input must be an array');
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
let left = 0;
|
|
15
|
-
let right = array.length - 1;
|
|
16
|
-
|
|
17
|
-
while (left <= right) {
|
|
18
|
-
const mid = Math.floor((left + right) / 2);
|
|
19
|
-
|
|
20
|
-
if (array[mid] === target) {
|
|
21
|
-
return mid;
|
|
22
|
-
} else if (array[mid] < target) {
|
|
23
|
-
left = mid + 1;
|
|
24
|
-
} else {
|
|
25
|
-
right = mid - 1;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return -1;
|
|
30
|
-
}
|
package/src/searching/index.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Линейный поиск
|
|
3
|
-
* @param {number[]} array - массив для поиска
|
|
4
|
-
* @param {number} target - целевое значение
|
|
5
|
-
* @returns {number} - индекс элемента или -1 если не найдено
|
|
6
|
-
* @time O(n)
|
|
7
|
-
* @space O(1)
|
|
8
|
-
*/
|
|
9
|
-
export function linearSearch(array, target) {
|
|
10
|
-
if (!Array.isArray(array)) {
|
|
11
|
-
throw new Error('Input must be an array');
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
for (let i = 0; i < array.length; i++) {
|
|
15
|
-
if (array[i] === target) {
|
|
16
|
-
return i;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return -1;
|
|
21
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Сортировка пузырьком
|
|
3
|
-
* @param {number[]} array - массив для сортировки
|
|
4
|
-
* @returns {number[]} - отсортированный массив
|
|
5
|
-
* @time O(n²)
|
|
6
|
-
* @space O(1)
|
|
7
|
-
*/
|
|
8
|
-
export function bubbleSort(array) {
|
|
9
|
-
if (!Array.isArray(array)) {
|
|
10
|
-
throw new Error('Input must be an array');
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const result = [...array];
|
|
14
|
-
const n = result.length;
|
|
15
|
-
|
|
16
|
-
for (let i = 0; i < n - 1; i++) {
|
|
17
|
-
for (let j = 0; j < n - i - 1; j++) {
|
|
18
|
-
if (result[j] > result[j + 1]) {
|
|
19
|
-
[result[j], result[j + 1]] = [result[j + 1], result[j]];
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
return result;
|
|
25
|
-
}
|
package/src/sorting/index.js
DELETED
package/src/sorting/mergeSort.js
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Сортировка слиянием
|
|
3
|
-
* @param {number[]} array - массив для сортировки
|
|
4
|
-
* @returns {number[]} - отсортированный массив
|
|
5
|
-
* @time O(n log n)
|
|
6
|
-
* @space O(n)
|
|
7
|
-
*/
|
|
8
|
-
export function mergeSort(array) {
|
|
9
|
-
if (!Array.isArray(array)) {
|
|
10
|
-
throw new Error('Input must be an array');
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
if (array.length <= 1) return array;
|
|
14
|
-
|
|
15
|
-
const mid = Math.floor(array.length / 2);
|
|
16
|
-
const left = mergeSort(array.slice(0, mid));
|
|
17
|
-
const right = mergeSort(array.slice(mid));
|
|
18
|
-
|
|
19
|
-
return merge(left, right);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function merge(left, right) {
|
|
23
|
-
const result = [];
|
|
24
|
-
let i = 0, j = 0;
|
|
25
|
-
|
|
26
|
-
while (i < left.length && j < right.length) {
|
|
27
|
-
if (left[i] <= right[j]) {
|
|
28
|
-
result.push(left[i]);
|
|
29
|
-
i++;
|
|
30
|
-
} else {
|
|
31
|
-
result.push(right[j]);
|
|
32
|
-
j++;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return [...result, ...left.slice(i), ...right.slice(j)];
|
|
37
|
-
}
|
package/src/sorting/quickSort.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Быстрая сортировка
|
|
3
|
-
* @param {number[]} array - массив для сортировки
|
|
4
|
-
* @returns {number[]} - отсортированный массив
|
|
5
|
-
* @time O(n log n) в среднем, O(n²) в худшем
|
|
6
|
-
* @space O(log n)
|
|
7
|
-
*/
|
|
8
|
-
export function quickSort(array) {
|
|
9
|
-
if (!Array.isArray(array)) {
|
|
10
|
-
throw new Error('Input must be an array');
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
if (array.length <= 1) return array;
|
|
14
|
-
|
|
15
|
-
const pivot = array[Math.floor(array.length / 2)];
|
|
16
|
-
const left = array.filter(x => x < pivot);
|
|
17
|
-
const middle = array.filter(x => x === pivot);
|
|
18
|
-
const right = array.filter(x => x > pivot);
|
|
19
|
-
|
|
20
|
-
return [...quickSort(left), ...middle, ...quickSort(right)];
|
|
21
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { binarySearch } from '../../searching/binarySearch';
|
|
2
|
-
|
|
3
|
-
describe('binarySearch', () => {
|
|
4
|
-
test('находит элемент в отсортированном массиве', () => {
|
|
5
|
-
const array = [1, 3, 5, 7, 9, 11];
|
|
6
|
-
expect(binarySearch(array, 7)).toBe(3);
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
test('возвращает -1 если элемент не найден', () => {
|
|
10
|
-
const array = [1, 3, 5, 7, 9];
|
|
11
|
-
expect(binarySearch(array, 6)).toBe(-1);
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
test('обрабатывает пустой массив', () => {
|
|
15
|
-
expect(binarySearch([], 5)).toBe(-1);
|
|
16
|
-
});
|
|
17
|
-
});
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { linearSearch } from '../../searching/linearSearch';
|
|
2
|
-
|
|
3
|
-
describe('linearSearch', () => {
|
|
4
|
-
test('находит элемент в отсортированном массиве', () => {
|
|
5
|
-
const array = [1, 3, 5, 7, 9, 11];
|
|
6
|
-
expect(linearSearch(array, 7)).toBe(3);
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
test('возвращает -1 если элемент не найден', () => {
|
|
10
|
-
const array = [1, 3, 5, 7, 9];
|
|
11
|
-
expect(linearSearch(array, 6)).toBe(-1);
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
test('обрабатывает пустой массив', () => {
|
|
15
|
-
expect(linearSearch([], 5)).toBe(-1);
|
|
16
|
-
});
|
|
17
|
-
});
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { bubbleSort } from '../../sorting/bubbleSort';
|
|
2
|
-
|
|
3
|
-
describe('bubbleSort', () => {
|
|
4
|
-
test('сортирует массив чисел правильно', () => {
|
|
5
|
-
const input = [5, 2, 8, 1, 9];
|
|
6
|
-
const expected = [1, 2, 5, 8, 9];
|
|
7
|
-
expect(bubbleSort(input)).toEqual(expected);
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
test('возвращает пустой массив для пустого входного', () => {
|
|
11
|
-
expect(bubbleSort([])).toEqual([]);
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
test('обрабатывает массив с одним элементом', () => {
|
|
15
|
-
expect(bubbleSort([42])).toEqual([42]);
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
test('вызывает ошибку для не-массива', () => {
|
|
19
|
-
expect(() => bubbleSort('not array')).toThrow('Input must be an array');
|
|
20
|
-
});
|
|
21
|
-
});
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { mergeSort } from '../../sorting/mergeSort';
|
|
2
|
-
|
|
3
|
-
describe('mergeSort', () => {
|
|
4
|
-
test('сортирует массив чисел правильно', () => {
|
|
5
|
-
const input = [5, 2, 8, 1, 9];
|
|
6
|
-
const expected = [1, 2, 5, 8, 9];
|
|
7
|
-
expect(mergeSort(input)).toEqual(expected);
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
test('возвращает пустой массив для пустого входного', () => {
|
|
11
|
-
expect(mergeSort([])).toEqual([]);
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
test('обрабатывает массив с одним элементом', () => {
|
|
15
|
-
expect(mergeSort([42])).toEqual([42]);
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
test('вызывает ошибку для не-массива', () => {
|
|
19
|
-
expect(() => mergeSort('not array')).toThrow('Input must be an array');
|
|
20
|
-
});
|
|
21
|
-
});
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { quickSort } from '../../sorting/quickSort';
|
|
2
|
-
|
|
3
|
-
describe('quickSort', () => {
|
|
4
|
-
test('сортирует массив чисел правильно', () => {
|
|
5
|
-
const input = [5, 2, 8, 1, 9];
|
|
6
|
-
const expected = [1, 2, 5, 8, 9];
|
|
7
|
-
expect(quickSort(input)).toEqual(expected);
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
test('возвращает пустой массив для пустого входного', () => {
|
|
11
|
-
expect(quickSort([])).toEqual([]);
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
test('обрабатывает массив с одним элементом', () => {
|
|
15
|
-
expect(quickSort([42])).toEqual([42]);
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
test('вызывает ошибку для не-массива', () => {
|
|
19
|
-
expect(() => quickSort('not array')).toThrow('Input must be an array');
|
|
20
|
-
});
|
|
21
|
-
});
|