-
분할정복과 병합정렬(merge sort), 퀵 정렬(quick sort)Programming/자료구조, 알고리즘 2020. 4. 1. 22:04반응형
분할 정복과 고급정렬
분할 정복
- 문제를 나눌 수 없을 때까지 나누어 각각을 풀고 다시 합병하여 문제의 답을 얻는 알고리즘
- 하향식 접근법으로 상위의 해답을 구하기 위해 아래로 내려가면서 하위의 해답을 구하는 방식
- 일반적으로 재귀함수로 구현된다.
- 문제를 잘게 쪼갤 때 부분 문제들은 서로 중복되지 않는다.
- 병합 정렬, 퀵 정렬 등
고급 정렬
1) 병합정렬
리스트를 절반으로 계속해서 자른다.
더이상 나눌 수 없을 만큼 나뉘었다면, 값을 비교 후 정렬해가며 병합한다.
리스트를 계속해서 나누는 함수와 나뉜 리스트를 정렬하며 합치는 함수를 만든다.
구현
// 병합 정렬 const mergeSort = arr => { // 재귀함수 종료 조건 if (arr.length <= 1) { return arr; } /** 1) 주어진 배열 나누기 */ const middle = parseInt(arr.length / 2, 10); // 주어진 배열의 가운데 인덱스 구하기 const left = mergeSort(arr.slice(0, middle)); // 첫 번째 요소부터 middle번째 요소 전까지 담긴 배열 const right = mergeSort(arr.slice(middle, arr.length)); // middle번째 요소부터 마지막 요소까지 담긴 배열 /** 2) 나뉜 값들 합치기 */ const result = []; // 정렬된 요소들이 담길 배열 let leftIndex = 0; // 왼쪽 배열 인덱스 초기화 let rightIndex = 0; // 오른쪽 배열 인덱스 초기화 // 2-1) left와 right 둘 다 있을 때 while (left.length > leftIndex && right.length > rightIndex) { if (left[leftIndex] > right[rightIndex]) { result.push(right[rightIndex]); // 둘을 비교하여 작은 값을 결과에 집어넣는다. rightIndex++; // 결과에 값을 집어넣은 쪽은 다음 요소로 이동한다. } else { result.push(left[leftIndex]); leftIndex++; } } // 2-2) left만 데이터가 남았을 때 while (left.length > leftIndex) { result.push(left[leftIndex]); leftIndex++; } // 2-3) right만 데이터가 남았을 때 while (right.length > rightIndex) { result.push(right[rightIndex]); rightIndex++; } return result; }; // 테스트 let example = []; for (let i = 0; i < 10; i++) { // 1~1000 범위의 난수 const item = Math.floor(Math.random() * 1000 + 1); example.push(item); } console.log(mergeSort(example));2) 퀵 정렬 quick sort
기준점(pivot)을 정해서 기준점보다 작은 데이터는 왼쪽, 큰 데이터는 오른쪽으로 모으는 함수를 작성한다.
각 왼쪽 오른쪽은 재귀함수를 사용해서 위 작업을 반복한다.
함수는 왼쪽, pivot, 오른쪽을 리턴한다.
구현
만약 리스트 내 요소의 개수가 한 개면 리스트 리턴
그렇지 않으면 리스트 맨 앞의 데이터를 기준점으로 놓기
left와 right 변수를 만들고 맨 앞의 데이터를 뺀 나머지 데이터를 기준점과 비교하여 기준점보다 작으면 left에 넣고 크면 right에 넣는다.
const quickSort = arr => { // 재귀함수 종료 조건 if (arr.length <= 1) { return arr; } // 배열 준비 const pivot = arr[0]; // 기준점 const left = []; // 기준점보다 작은 값 const right = []; // 기준점보다 큰 값 // 기준점 다음 요소부터 정렬 시작 for (let i = 1; i < arr.length; i++) { if (arr[i] < pivot) { left.push(arr[i]); } else if (arr[i] > pivot) { right.push(arr[i]); } } return [...quickSort(left), ...[pivot], ...quickSort(right)]; }; const sorted = quickSort([123, 234, 236, 5, 2, 1, 7, 8, 9, 11, 345]); console.log(sorted);마지막 배열을 return 하는 방법은
Array.prototype.concat()을 이용하거나...spread기법을 사용할 수 있다.// Array.prototype.concat() 메소드로 배열 이어붙이기 return quickSort(left).concat(pivot, quickSort(right)); // ...spread 이용 return [...quickSort(left), ...pivot, ...quickSort(right)];반응형'Programming > 자료구조, 알고리즘' 카테고리의 다른 글
순차 탐색 (0) 2020.04.05 그리디 알고리즘 (2) 2020.04.03 동적계획법과 피보나치 수열 (0) 2020.03.31 자바스크립트로 구현하는 재귀함수, 재귀호출 (0) 2020.03.31 자바스크립트로 구현하는 기본 정렬들 - 버블 정렬, 선택 정렬 (0) 2020.03.31