분할 정복(Divide and Conquer) : 문제를 가장 작은 단위로 분리하고 각각 해결 후 결과를 한곳에 모아서 문제를 해결하는 방식
빠른 정렬(Quick Sort)
- 배열에서 기준점을 구한 후 기준점을 기준으로 배열을 나눕니다.(한쪽에는 기준점보다 큰 항목 다른 한쪽은 기준점보다 작은 항목)
- 분할 정복 방법을 통해 배열을 정렬 합니다.
- 불안정 정렬에 속하며 다른 원소와의 비교만으로 정렬을 수행하는 비교 정렬입니다.
장점
- 초기에 결정된 피벗(기준점)들은 연산에서 제외되고, 피벗을 통해 나눠진 배열의 데이터들의 불필요한 데이터 이동을 줄여서 시간측면에서 굉장히 빠릅니다.
- 배열 안에서 교환하기 때문에 다른 메모리 공간이 필요하지 않습니다.
단점
- 구현하기 어렵습니다.
- 불안정 정렬입니다.
- 정렬된 배열에서는 불균형 분할에 의해 오히려 수행 시간이 더 오래 걸립니다.
CODE
function quickSort(arr) {
return quickSortHelper(arr, 0, arr.length-1)
}
function quickSortHelper(arr, left, right) {
if(left<right) {
var index = partition(arr, left, right)
quickSortHelper(arr, left, index-1);
quickSortHelper(arr, index+1, right)
}
return arr
}
function partition(arr, left, right) {
var pivot = arr[right];
var i = (left-1);
for(var j=left; j<=right-1; j++) {
if(arr[j] <=pivot) {
i++
swap(arr, i, j)
}
}
swap(arr, i+1, right)
return (i+1);
}
function swap(arr, index1, index2) {
var temp = arr[index1];
arr[index1] = arr[index2]
arr[index2] = temp;
}
console.log(quickSort([1,7,5,2,3,4]))
설명
function quickSort(arr) {
return quickSortHelper(arr, 0, arr.length-1)
}
function quickSortHelper(arr, left, right) {
if(left<right) {
var index = partition(arr, left, right)
console.log('초기 기준점(4)을 기준으로 왼쪽 항목 분할')
quickSortHelper(arr, left, index-1);
console.log("")
console.log('초기 기준점에서 오른쪽 항목 분할')
if(index<right) {
console.log(`초기 기준점 : 4 left : ${index+1}`)
console.log(`left가 초기 기준점 오른쪽에 위치해서 높아서 분할 합니다`)
console.log("")
quickSortHelper(arr, index+1, right)
} else {
console.log(`초기 기준점 : 4 left : ${index}`)
console.log(`left가 초기 기준점 보다 왼쪽에 있거나 배열의크기 보다 커서 분할하지 않습니다`)
console.log("")
}
}
return arr
}
function partition(arr, left, right) {
console.log('정복 함수 실행')
console.log(arr, `left : ${left}, right : ${right}`)
var pivot = arr[right];
var i = (left-1);
for(var j=left; j<=right-1; j++) {
if(arr[j] <=pivot) {
i++
console.log(`i : ${i}, j : ${j}, ${arr[j]} < ${pivot}`)
swap(arr, i, j)
}
}
console.log("")
console.log(i+1, right)
swap(arr, i+1, right)
return (i+1);
}
function swap(arr, index1, index2) {
var temp = arr[index1];
arr[index1] = arr[index2]
arr[index2] = temp;
}
console.log(quickSort([1,7,5,2,3,4]))
// 정복 함수 실행
// [ 1, 7, 5, 2, 3, 4 ] left : 0, right : 5
// i : 0, j : 0, 1 < 4
// i : 1, j : 3, 2 < 4
// i : 2, j : 4, 3 < 4
//
// 초기 기준점(4)을 기준으로 왼쪽 항목 분할
// 정복 함수 실행
// [ 1, 2, 3, 4, 5, 7 ] left : 0, right : 2
// i : 0, j : 0, 1 < 3
// i : 1, j : 1, 2 < 3
//
// 초기 기준점(4)을 기준으로 왼쪽 항목 분할
// 정복 함수 실행
// [ 1, 2, 3, 4, 5, 7 ] left : 0, right : 1
// i : 0, j : 0, 1 < 2
//
// 초기 기준점(4)을 기준으로 왼쪽 항목 분할
//
// 초기 기준점에서 오른쪽 항목 분할
// 초기 기준점 : 4 left : 1
// left가 초기 기준점 보다 왼쪽에 있거나 배열의크기 보다 커서 분할하지 않습니다
//
//
// 초기 기준점에서 오른쪽 항목 분할
// 초기 기준점 : 4 left : 2
// left가 초기 기준점 보다 왼쪽에 있거나 배열의크기 보다 커서 분할하지 않습니다
//
//
// 초기 기준점에서 오른쪽 항목 분할
// 초기 기준점 : 4 left : 4
// left가 초기 기준점 오른쪽에 위치해서 높아서 분할 합니다
//
// 정복 함수 실행
// [ 1, 2, 3, 4, 5, 7 ] left : 4, right : 5
// i : 4, j : 4, 5 < 7
//
// 초기 기준점(4)을 기준으로 왼쪽 항목 분할
//
// 초기 기준점에서 오른쪽 항목 분할
// 초기 기준점 : 4 left : 5
// left가 초기 기준점 보다 왼쪽에 있거나 배열의크기 보다 커서 분할하지 않습니다
//
// [ 1, 2, 3, 4, 5, 7 ]
'자료구조' 카테고리의 다른 글
해시 테이블(Hash Table) (0) | 2020.07.08 |
---|---|
병합 정렬(Merge Sort) (0) | 2020.07.07 |
삽입 정렬(Insertion Sort) (0) | 2020.07.02 |
선택 정렬(Selection Sort) (0) | 2020.07.01 |
거품 정렬(Bubble Sort) (0) | 2020.07.01 |