오름차순
, 내림차순
내부정렬
외부정렬
이웃한 두 원소의 대소 관계를 비교하여 필요에 따라 교환을 반복하는 알고리즘
단순 교환 정렬이라고도 함
패스
function bubbleSort(arr) {
const n = arr.length;
let k = 0;
while (k < n - 1) {
last = n - 1;
for (let j = 0; j < n - 1 - k; j++) {
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
last = j; // 마지막으로 교환이 발생한 위치 기록
}
}
k = last; // 마지막으로 교환된 위치까지만 정렬
}
return arr;
}
last
에저장 후 다음 for문 돌 때 마지막 인덱스가 저장되어 있는 last
이전 까지만 스캔 범위를 제한하여 정렬하는 방법가장 작은 원소부터 선택해 알맞은 위치로 옮기는 작업을 반복하여 정렬하는 알고리즘
안정적이지 않음
[3L, 4, 2, 3R, 1] --> 3L <-> 1
[1, 4, 2, 3R, 3L] --> 4 <-> 2
[1, 2, 4, 3R, 3L] --> 4 <-> 3R
[1, 2, 3R, 4, 3L] --> 4 <-> 3L
[1, 2, 3R, 3L, 4] --> 정렬 완료
function selectionSort(arr) {
const n = arr.length;
for (let i = 0; i < n - 1; i++) {
let min = i;
// j는 i + 1부터 배열 끝까지 비교해야 함
for (let j = i + 1; j < n; j++) {
if (arr[j] < arr[min]) {
min = j;
}
}
// 최솟값을 i번째 요소와 교환
[arr[i], arr[min]] = [arr[min], arr[i]];
}
return arr;
}
주목한 원소보다 더 앞쪽에서 알맞은 위치로 삽입하며 정렬하는 알고리즘
단순 선택 정렬과 비슷해 보이지만 값이 가장 작은 원소를 선택하지 않는다는 점이 다름
카드를 한 줄로 늘어놓을 때 사용하는 방법과 비슷함
장점 : 이미 정렬을 마쳤거나 정렬이 거의 끝나가는 상태에서는 속도가 아주 빠르다
단점 : 삽입할 위치가 멀리 떨어져 있으면 이동 횟수가 많아짐
종료 조건
계산 조건
function insertionSort(arr) {
const n = arr.length;
for (let i = 1; i < n; i++) {
let j = i;
temp = arr[i]; // 현재 삽입할 원소를 임시로 저장
// j보다 앞에 있는 원소들과 비교하여 적절한 위치를 찾음
while (j > 0 && arr[j - 1] > temp) {
arr[j] = arr[j - 1]; // 원소가 크면 한 칸씩 뒤로 이동
j -= 1; // 한 칸 앞으로 이동하여 다음 비교
}
arr[j] = temp;
}
return arr;
}
먼저 정렬할 배열의 원소를 그룹으로 나눠 각 그룹별로 정렬을 수행한 후
정렬된 그룹을 합치는 작업을 반복하여 정렬하는 방식
[8, 1, 4, 2, 7, 6, 3, 5]
// 4칸 떨어진 원소 2개 정렬
(8, 7) => (7, 8)
(1, 6) => (1, 6)
(4, 3) => (3, 4)
(2, 5) => (2, 5)
// 결과
[7, 1, 3, 2, 8, 6, 4, 5]
// 2칸 떨어진 원소 4개 정렬
(7, 3, 8 ,4) => (3, 4, 7, 8)
(1, 2, 6, 5) => (1, 2, 5, 6)
// 결과
[3, 1, 4, 2, 7, 5, 8, 6]
// 1칸 떨어진 원소 8개 정렬
(3, 1, 4, 2, 7, 5, 8, 6) => (1, 2, 3, 4, 5, 6, 7, 8)
function shellSort(arr) {
const n = arr.length;
h = Math.floor(n / 2); // 초기 gap을 배열 크기의 절반으로 설정
while (h > 0) {
for (let i = h; i < n; i++) {
let j = i - h;
let temp = arr[i]; // 현재 비교할 원소 저장
while (j >= 0 && arr[j] > temp) {
arr[j + h] = arr[j]; // 값을 오른쪽으로 이동
j -= h;
}
arr[j + h] = temp; // temp 값을 올바른 위치에 삽입
}
h = Math.floor(h / 2); // gap을 줄임
}
return arr;
}
가장 빠른 정렬 알고리즘
요소를 선택하여 기준으로 삼고 그 기준을 바탕으로 오버, 언더로 그룹을 나눔
다시 각 그룹에서 피벗을 선택하여 나누기를 반복하며 모든 그룹이 1명씩 남으면 정렬이 완료
- 피벗(중심축) : 기준으로 삼은 요소
- 2개로 나눈 그룹 어디에 넣어도 상관 없다
교환
while (pl <= pr) {
while (arr[pl] < x) {
pl += 1;
}
while (arr[pr] > x) {
pr -= 1;
}
if (pl <= pr) {
[arr[pl], arr[pr]] = [arr[pr], arr[pl]];
pl += 1;
pr -= 1;
}
function dividePivot(arr, left, right) {
let pl = left;
let pr = right;
x = arr[Math.floor((left + right) / 2)];
while (pl <= pr) {
while (arr[pl] < x) {
pl += 1;
}
while (arr[pr] > x) {
pr -= 1;
}
if (pl <= pr) {
[arr[pl], arr[pr]] = [arr[pr], arr[pl]];
pl += 1;
pr -= 1;
}
}
// 좌우 각그룹을 다시 나누기 위해 재귀 호출
if (left < pr) dividePivot(arr, left, pr);
if (right > pl) dividePivot(arr, pl, right);
return arr;
}
function quickSort(array) {
const a = dividePivot(array, 0, array.length - 1);
console.log(a);
}