Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sorting Algorithms #28

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions src/algorithms/sorting/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Sorting algorithms

The assumptions is that the algorithms will be sorting numeric arrays.

## Classification

Sorting algorithms can be classified by:

- Computational complexity
Best, worst and average case behavior in terms of the size of the list. For typical serial sorting algorithms, good behavior is O(n log n), with parallel sort in O(log2 n), and bad behavior is O(n2). Ideal behavior for a serial sort is O(n), but this is not possible in the average case. Optimal parallel sorting is O(log n).
Swaps for "in-place" algorithms.
- Memory complexity. In particular, some sorting algorithms are "in-place". Strictly, an in-place sort needs only O(1) memory beyond the items being sorted; sometimes O(log n) additional memory is considered "in-place".
- Recursion: Some algorithms are either recursive or non-recursive, while others may be both (e.g., merge sort).
- Stability: stable sorting algorithms maintain the relative order of records with equal keys (i.e., values).
- Whether or not they are a comparison sort. A comparison sort examines the data only by comparing two elements with a comparison operator.
- General method: insertion, exchange, selection, merging, etc. Exchange sorts include bubble sort and quicksort. Selection sorts include cycle sort and heapsort.
- Whether the algorithm is serial or parallel. The remainder of this discussion almost exclusively concentrates upon serial algorithms and assumes serial operation.
- Adaptability: Whether or not the presortedness of the input affects the running time. Algorithms that take this into account are known to be adaptive.
- Online: An algorithm such as Insertion Sort that is online can sort a constant stream of input.
75 changes: 75 additions & 0 deletions src/algorithms/sorting/bubble-sort.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import SortingOrder from 'src/util/SortingOrder';
import { bubbleSort, sort } from './bubble-sort';

const params = [
{
label: 'Reverse ordering for Ascending',
input: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0],
sortingOrder: SortingOrder.Ascending,
expected: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
},
{
label: 'Reverse ordering for Descending',
input: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
sortingOrder: SortingOrder.Descending,
expected: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0],
},
{
label: 'Same Ascending order',
input: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
sortingOrder: SortingOrder.Ascending,
expected: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
},
{
label: 'Same Descending order',
input: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0],
sortingOrder: SortingOrder.Descending,
expected: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0],
},
{
label: 'Randomly sorted with duplicates for Ascending',
input: [15, 2, 4, 1, 7, 22, 5, -3, 9, -4, 5, 49, 993, 1, 10, 1, 111, 9, 2],
sortingOrder: SortingOrder.Ascending,
expected: [],
},
{
label: 'Randomly sorted with duplicates for Descending',
input: [15, 2, 4, 1, 7, 22, 5, -3, 9, -4, 5, 49, 993, 1, 10, 1, 111, 9, 2],
sortingOrder: SortingOrder.Descending,
expected: [],
},
{
label: 'Only one element for Ascending',
input: [7],
sortingOrder: SortingOrder.Ascending,
expected: [7],
},
{
label: 'Only one element for Descending',
input: [7],
sortingOrder: SortingOrder.Descending,
expected: [7],
},
{
label: 'Empty array for Ascending',
input: [],
sortingOrder: SortingOrder.Ascending,
expected: [],
},
{
label: 'Empty array for Descending',
input: [],
sortingOrder: SortingOrder.Descending,
expected: [],
},
];

test.each(params)('bubbleSort - $label', ({ input, sortingOrder, expected }) => {
bubbleSort(input, sortingOrder);
expect(input).toEqual(expected);
});

test.each(params)('sort - $label', ({ input, sortingOrder, expected }) => {
sort(input, sortingOrder);
expect(input).toEqual(expected);
});
59 changes: 59 additions & 0 deletions src/algorithms/sorting/bubble-sort.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import SortingOrder from 'src/util/SortingOrder';

export function bubbleSort(input: number[], sortingOrder: SortingOrder) {
if (input.length <= 1) return;

for (let i = 0; i < input.length - 1; i++) {
for (let j = i + 1; j < input.length; j++) {
if (
(sortingOrder === SortingOrder.Ascending && input[i] > input[j]) ||
(sortingOrder === SortingOrder.Descending && input[i] < input[j])
) {
const temp = input[j];
input[j] = input[i];
input[i] = temp;
}
}
}
}

// 5 3 10 11 7 9
// 3 5 10 11 7 9
// 3 5 10 11 7 9
// 3 5 10 11 7 9
// 3 5 10 7 11 9
// 3 5 10 7 9 11
// 3 5 10 7 9 11
// 3 5 10 7 9 11
// 3 5 7 10 9 11
// 3 5 7 9 10 11

export function sort(input: number[], sortingOrder: SortingOrder) {
if (input.length <= 1) return;

let swap = true;
let j = 1;

while (swap) {
let atLeastOneSwap = false;

for (let i = 0; i < input.length - j; i++) {
if (
(sortingOrder === SortingOrder.Ascending && input[i] > input[i + 1]) ||
(sortingOrder === SortingOrder.Descending && input[i] < input[i + 1])
) {
const temp = input[i + 1];
input[i + 1] = input[i];
input[i] = temp;
atLeastOneSwap = true;
}
console.log(input);
}

if (!atLeastOneSwap) {
swap = false;
} else {
j++;
}
}
}