거품(버블)정렬
- 가까운 두 원소를 비교해서 정렬하는 방식이다.
O(N^2)
- 코드가 단순하고 구현하기 쉽다
- 느리다.
function bubbleSort(arr){
for (var i=arr.length-1; i>=0; i--){
for(var j=1; j<=i; j++){
if(arr[j-1]>arr[j]){
var temp = arr[j-1];
arr[j-1] = arr[j];
arr[j] = temp;
}
}
}
return arr;
}
선택정렬
- 배열에서 가장 작은 값을 찾아, 그 값을 배치 한다.
O(N^2)
- 코드가 단순하고 구현하기 쉽다.
- 느리다.
function selectionSort(arr){
var minIndex, temp, len=arr.length;
for(var i=0; i < len; i++){
minIndex = i;
for(var j = i+1; j<len; j++){
if(arr[j]<arr[minIndex]){
minIndex = j;
}
}
temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
return arr;
}
삽입정렬
- 배열의 요소를 차례대로 순회하면서, 이미 정렬된 배열과 비교하여 해당 요소를 올바른 위치에 삽입하는 것
O(N^2)
- 구현하기 쉽다
- 배열이 길어질 수록 정렬할 경우의 수가 많아져서 느려진다.
function insertionSort(arr) {
const result = [...arr];
for (let i = 1; i < result.length; i++) {
let temp = result[i];
let aux = i - 1;
while (aux >= 0 && result[aux] > temp) {
result[aux + 1] = result[aux];
aux--;
}
result[aux + 1] = temp;
}
return result;
}
퀵정렬
- 리스트 가운데에서 하나의 원소를 고른다. 이 원소를 피벗이라고 한다.
- 피벗을 기준으로 피벗 앞에는 피벗 보다 작은 값을, 뒤에는 큰 값들이 오도록하고 그렇게 리스트를 둘로 나눈다.
- 분할된 리스트에 대해 이 작업을 리스트의 크기가 0 또는 1이 될 때까지 반복한다.
- 제법 빠르지만, 별도의 메모리 공간이 필요해서 공간 낭비가 있다.
function quickSort (array) {
if (array.length < 2) {
return array;
}
const pivot = [array[0]];
const left = [];
const right = [];
for (let i = 1; i < array.length; i++) {
if (array[i] < pivot) {
left.push(array[i]);
} else if (array[i] > pivot) {
right.push(array[i]);
} else {
pivot.push(array[i]);
}
}
return [quickSort(left).concat(pivot, quickSort(right))].flat(Infinity);
}
병합정렬
- 정렬되지 않은 리스트를 반으로 잘라 비슷한 크기의 두 배열로 나눈다. (길이가 1이면 정렬되었다고 본다)
- 분할된 각 원소에 대해 비교하여 정렬하고 합친다.
- 위 과정을 반복한다.
O(N * logN)
function mergeSort(arr) {
if (arr.length === 1) return arr
const middleIndex = Math.floor(arr.length / 2)
const left = arr.slice(0, middle)
const right = arr.slice(middle)
return merge(mergeSort(left), mergeSort(right))
}
function merge(left, right) {
const result = []
let leftIndex = 0;
let rightIndex = 0;
while (leftIndex < left.length && rightIndex < right.index) {
if (left[leftIndex] < right[rightIndex]) {
result.push(left[leftIndex])
leftIndex++
} else {
result.push(right[rightIndex])
rightIndex++
}
}
return [...result, ...left.slice(leftIndex), ...right.slice(rightIndex)]
}