~51일차~
코딩테스트 스터디에서 강의를 듣고 정리해보았다.
//선택 정렬 함수
function selectionSort(arr) {
for (let i= 0; i <arr.length; i++) {
let minIndex = i; // 가장 작은 원소의 인덱스
for (let j = i +1; j < arr.length; j++) {
if (arr[minIndex] > arr[j] {
minIndex = j;
}
}
//스와프(swap)
let temp = arr[i];
arr[i] = arr[minIndex];
arr[min Index] = temp;
}
}
//버블 정렬 함수
function bubbleSort(arr) {
for (let i = arr.length - 1; i > 0; i--) {
for (let j = 0; j < i; j++) {
if (arr[j] < arr[j + i]) {
let temp = arr[j];
arr[j] = arr[j + i];
arr[j + 1] = temp;
}
}
}
}
각 단계에서 현재 원소가 삽입될 위치를 찾는다
적절한 위치에 도달할 때까지 반복적으로 왼쪽으로 이동
동작과정이 매우 직관적이나, O(N2)의 시간 복잡도를 가져 비효율적
처음에 첫번째 원소는 정렬이 되어 있다고 고려
선택적보다는 효율적일 수 있음
//삽입 정렬 함수
function insertionSort(arr) {
for (let i =1; i < arr.length; i++) {
for (let j = i; j > 0; j--) {
// 인덱스 j부터 1까지 1씩 감소하며 반복
if (arr[j] < arr[j-i]) {
// 한 칸씩 왼쪽으로 이동
//스와프(swap)
let temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
} else {
// 작은 데이터를 만나면 그 위치에서 멈춤
break;
}
}
}
}
-각 원소를 적절한 위치에 삽입하는 정렬 기법
-일반적으로 재귀 함수를 이용하여 구현
-> 큰 문제를 작은 문제로 "분할하는 방식이 동일한" 경우가 많기 때문
-더 이상 쪼갤 수 없는 크기가 될 때까지 계속하여 분할
시간 복잡도 O(NlogN)을 보장하는 빠른 정렬 알고리즘 중 하나
분할 정복을 이용하는 가장 기본적인 정렬알고리즘
1. 분할(divide) : 정렬할배열(큰 문제)을 같은 크기의 부분 배열(작은 문제) 2개로 분할
2. 정복(conquer): 부분 배열 정렬
3. 조합(combine): 정렬된 부분 배열을 하나의 배열로 다시 병합
직관적으로 생각
-> 높이가 O(logN), 너비 O(N)인 정사각형과 유사
//(정복 이후) 병합(merge) !!수행!! 함수
function merge(arr, left, mid, right) {
let i = left; //왼쪽 배열에서 첫번째 원소를 가르킴
let j = mid + 1; // 오른쪽 배열에서 첫번째 원소를 가르킴
let k = left; // 결과 배열의 인덱스
// 각각 한칸씩 오른쪽으로 움직이며 비교
while (i <= mid && j <= right) {
// 왼쪽을 가리키는 값 <= 오른쪽을 가리키는 값
if (arr[i] <= arr[j]) sorted[k++] = arr [i++]; // 더 작은 값이 결과 배열에 들어감(오름차순 형태)
else sorted[k++] = arr[j++];
}
// 왼쪽 배열에 대한 처리가 다 끝난 경우
if (i > mid) {
for (; j <= right; j++) sorted[k++] = arr[j];
}
//오른쪽 배열에 대한 처리가 다 끝난 경우
else {
for (; <= mid; i++) sorted[k++] = arr[i];
}
// 정렬된 배열 결과를 원본 배열에 반영하기
for (let x = left; x <= right; x++) {
arr[x] = sorted[x];
}
}
//실질적 병합 정렬(merge sort) 함수
//left:첫번째 원소의 인덱스, right:마지막 원소의 인덱스
function mergeSort(arr, left, right) {
//원소가 1개인 경우 해당 배열은 정렬이 된 상태로 이해 가능
if (left < right) {
//원소가 2개 이상이라면
let mid = parseInt((left + right) / 2); //2개 부분 배열로 분할 (divide)
mergeSort(arr, left, mid); // 왼쪽 부분 배열 정렬 수행(conquer)
mergeSort(arr, mid + 1,, right); // 오른쪽 부분 배열 정렬 수행(conquer)
merge(arr, left, mid, right); // 정렬된 2개의 배열을 하나로 병합(combine)
}
}