mirror of
https://github.moeyy.xyz/https://github.com/trekhleb/javascript-algorithms.git
synced 2024-11-14 06:52:59 +08:00
Add files via upload
This commit is contained in:
parent
b7bacf8870
commit
508e4d1313
@ -0,0 +1,59 @@
|
|||||||
|
import Sort from '../Sort';
|
||||||
|
|
||||||
|
export default class CocktailShakerSort extends Sort {
|
||||||
|
sort(originalArray) {
|
||||||
|
// Flag that holds info about whether the swap has occur or not.
|
||||||
|
let swapped = true;
|
||||||
|
// Clone original array to prevent its modification.
|
||||||
|
const array = [...originalArray];
|
||||||
|
|
||||||
|
let start = 0;
|
||||||
|
let end = array.length;
|
||||||
|
|
||||||
|
while (swapped) {
|
||||||
|
// Reset the swapped flag on entering the loop,
|
||||||
|
// because it might be true from a previous iteration.
|
||||||
|
swapped = false;
|
||||||
|
|
||||||
|
// Loop forward same as the bubble sort
|
||||||
|
for (let i = start; i < end - 1; i += 1) {
|
||||||
|
// Call visiting callback.
|
||||||
|
this.callbacks.visitingCallback(array[i]);
|
||||||
|
|
||||||
|
if (this.comparator.greaterThan(array[i], array[i + 1])) {
|
||||||
|
[array[i], array[i + 1]] = [array[i + 1], array[i]];
|
||||||
|
swapped = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move the end point backward by one,
|
||||||
|
// because the item at the end point is already in its correct position.
|
||||||
|
end -= 1;
|
||||||
|
|
||||||
|
// If nothing swapped, then array is sorted.
|
||||||
|
if (swapped === false) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the swapped flag so that it can be used in the next stage
|
||||||
|
swapped = false;
|
||||||
|
|
||||||
|
// Loop backward, doing the same comparison as in the previous stage
|
||||||
|
for (let i = end - 1; i >= start; i -= 1) {
|
||||||
|
// Call visiting callback.
|
||||||
|
this.callbacks.visitingCallback(array[i]);
|
||||||
|
|
||||||
|
if (this.comparator.greaterThan(array[i], array[i + 1])) {
|
||||||
|
[array[i], array[i + 1]] = [array[i + 1], array[i]];
|
||||||
|
swapped = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move the start point forward by one,
|
||||||
|
// because the item at the start point is already in its correct position.
|
||||||
|
start += 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
}
|
23
src/algorithms/sorting/cocktail-shaker-sort/README.md
Normal file
23
src/algorithms/sorting/cocktail-shaker-sort/README.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Cocktail Shaker Sort
|
||||||
|
|
||||||
|
_Read this in other languages:_
|
||||||
|
[_简体中文_](README.zh-CN.md)
|
||||||
|
|
||||||
|
Cocktail Shaker Sort is an algorithm that is a Bidirectional Bubble Sort.
|
||||||
|
|
||||||
|
The algorithm extends bubble sort by operating in two directions.
|
||||||
|
While it improves on bubble sort by more quickly moving items to the beginning of the list, it provides only marginal performance improvements.
|
||||||
|
|
||||||
|
![Algorithm Visualization](https://upload.wikimedia.org/wikipedia/commons/e/ef/Sorting_shaker_sort_anim.gif)
|
||||||
|
|
||||||
|
## Complexity
|
||||||
|
|
||||||
|
| Name | Best | Average | Worst | Memory | Stable | Comments |
|
||||||
|
| ------------------------------ | :-------------: | :-----------------: | :-----------------: | :-------: | :-------: | :-------- |
|
||||||
|
| **Cocktail Shaker Sort** | n | n<sup>2</sup> | n<sup>2</sup> | 1 | Yes | |
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [Cocktail Shaker Sort on Wikipedia](https://en.wikipedia.org/wiki/Cocktail_shaker_sort)
|
||||||
|
|
||||||
|
- [Bubble Sort on Wikipedia](https://en.wikipedia.org/wiki/Bubble_sort)
|
23
src/algorithms/sorting/cocktail-shaker-sort/README.zh-CN.md
Normal file
23
src/algorithms/sorting/cocktail-shaker-sort/README.zh-CN.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# 鸡尾酒排序
|
||||||
|
|
||||||
|
_Read this in other languages:_
|
||||||
|
[_English_](README.md)
|
||||||
|
|
||||||
|
鸡尾酒排序是一种双向气泡排序的算法。
|
||||||
|
|
||||||
|
该算法通过在两个方向上操作扩展了冒泡排序。虽然它通过更快速地将项目移到列表的开头而改进了冒泡排序,但它只提供了微弱的性能改进。
|
||||||
|
|
||||||
|
![Algorithm Visualization](https://upload.wikimedia.org/wikipedia/commons/e/ef/Sorting_shaker_sort_anim.gif)
|
||||||
|
|
||||||
|
|
||||||
|
## 复杂度
|
||||||
|
|
||||||
|
| 名称 | 最优 | 平均 | 最坏 | 内存 | 稳定 | 备注 |
|
||||||
|
| ------------------------------ | :-------------: | :-----------------: | :-----------------: | :-------: | :-------: | :-------- |
|
||||||
|
| **鸡尾酒排序** | n | n<sup>2</sup> | n<sup>2</sup> | 1 | 是 | |
|
||||||
|
|
||||||
|
## 参考
|
||||||
|
|
||||||
|
- [鸡尾酒排序(维基百科)](https://zh.wikipedia.org/wiki/%E9%B8%A1%E5%B0%BE%E9%85%92%E6%8E%92%E5%BA%8F)
|
||||||
|
|
||||||
|
- [冒泡排序(维基百科)](https://zh.wikipedia.org/wiki/%E5%86%92%E6%B3%A1%E6%8E%92%E5%BA%8F)
|
@ -0,0 +1,64 @@
|
|||||||
|
import CocktailShakerSort from '../CocktailShakerSort';
|
||||||
|
import {
|
||||||
|
equalArr,
|
||||||
|
notSortedArr,
|
||||||
|
reverseArr,
|
||||||
|
sortedArr,
|
||||||
|
SortTester,
|
||||||
|
} from '../../SortTester';
|
||||||
|
|
||||||
|
// Complexity constants.
|
||||||
|
const SORTED_ARRAY_VISITING_COUNT = 19;
|
||||||
|
const NOT_SORTED_ARRAY_VISITING_COUNT = 159;
|
||||||
|
const REVERSE_SORTED_ARRAY_VISITING_COUNT = 200;
|
||||||
|
const EQUAL_ARRAY_VISITING_COUNT = 19;
|
||||||
|
|
||||||
|
describe('CocktailShakerSort', () => {
|
||||||
|
it('should sort array', () => {
|
||||||
|
SortTester.testSort(CocktailShakerSort);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should sort array with custom comparator', () => {
|
||||||
|
SortTester.testSortWithCustomComparator(CocktailShakerSort);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should do stable sorting', () => {
|
||||||
|
SortTester.testSortStability(CocktailShakerSort);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should sort negative numbers', () => {
|
||||||
|
SortTester.testNegativeNumbersSort(CocktailShakerSort);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should visit EQUAL array element specified number of times', () => {
|
||||||
|
SortTester.testAlgorithmTimeComplexity(
|
||||||
|
CocktailShakerSort,
|
||||||
|
equalArr,
|
||||||
|
EQUAL_ARRAY_VISITING_COUNT,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should visit SORTED array element specified number of times', () => {
|
||||||
|
SortTester.testAlgorithmTimeComplexity(
|
||||||
|
CocktailShakerSort,
|
||||||
|
sortedArr,
|
||||||
|
SORTED_ARRAY_VISITING_COUNT,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should visit NOT SORTED array element specified number of times', () => {
|
||||||
|
SortTester.testAlgorithmTimeComplexity(
|
||||||
|
CocktailShakerSort,
|
||||||
|
notSortedArr,
|
||||||
|
NOT_SORTED_ARRAY_VISITING_COUNT,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should visit REVERSE SORTED array element specified number of times', () => {
|
||||||
|
SortTester.testAlgorithmTimeComplexity(
|
||||||
|
CocktailShakerSort,
|
||||||
|
reverseArr,
|
||||||
|
REVERSE_SORTED_ARRAY_VISITING_COUNT,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user