일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- graph
- java
- ec2
- datastructure
- Queue
- 이진탐색트리
- BinaryTree
- bubblesort
- 트리
- Recursion
- Tomcat
- 자료구조
- ADT
- heap
- BinarySearchTree
- C
- MariaDB
- 알고리즘
- 큐
- web
- C언어
- 버블정렬
- aws
- data structure
- algorithm
- 그래프
- spring
- 리스트
- Stack
- 웹서버
- Today
- Total
Min'sLog
(자료구조) 퀵 정렬(Quick Sort) 본문
● 퀵 정렬(quick sort) 이란
‘ 찰스 앤터니 리처드 호어(Charles Antony Richard Hoare)’가 개발한 정렬 알고리즘
퀵 정렬은 불안정 정렬 에 속하며, 다른 원소와의 비교만으로 정렬을 수행하는 비교 정렬 에 속한다.
분할 정복 알고리즘(Divide and Conquer)의 하나로, 평균적으로 매우 빠른 수행 속도를 자랑하는 정렬 방법
● 퀵정렬 : 정렬 방법 정리
분할 정복(Divide Conquer)을 활용한 순환호출로 구현한다.
○ 퀵정렬 과정
1. 리스트 안에 있는 한 요소를 선택한다. 이렇게 고른 원소를 피벗(pivot) 이라고 한다.
2. 피벗을 기준으로 피벗보다 작은 요소들은 모두 피벗의 왼쪽으로 옮겨지고
피벗보다 큰 요소들은 모두 피벗의 오른쪽으로 옮긴다.
3. 피벗을 제외한 왼쪽 리스트와 오른쪽 리스트를 다시 정렬한다.
4. 분할된 부분 리스트에 대하여 순환 호출 을 이용하여 정렬을 반복한다.(부분 리스트에서도 피벗을 선출)
5. 리스트의 크기가 0이나 1이 될 때까지 반복한다.
● 퀵 정렬 : 이해를 위한 변수중심의 코드 구현 방식 설명
※ 변수 정의
- left : 정렬대상의 왼쪽 지점
- right : 정렬대상의 오른쪽 지점
- pivot : 중심축 지점
- low : 피벗을 제외한 가장 왼쪽에 위치한 지점
- high : 피벗을 제외한 가장 오른쪽에 위치한 지점
(※ 코드의 구현은 left (최좌측 리스트)를 Pivot 으로 지정)
○ low와 high 는 Pivot 을 기준으로 해당 위치를 움직이는 Index 이다.
- low는 오른쪽으로 이동 -> 피벗보다 큰값을 만날 때까지 low Index 는 증가
- high는 왼쪽으로 이동 -> 피벗보다 작은 값을 만날 때까지 high Indext 는 감소
○ low와 high 의 Index 조건이 알맞게 되면 해당 위치 리스트들을 swap 한다.
○ 해당 반복은 high와 low가 index가 역전되면 멈추게 된다.
○ high와 low가 역전되면, 피벗과 high의 데이터 교환한다.
○ 피봇위치를 기점으로 두개의 영역으로 나누어 반복 실행한다.
● 구현
○ 퀵 정렬 Partition Function
int Partition(int arr[],int left,int right){
int pivot = arr[left];
int low = left+1;
int high = right;
while(low <=high){
// pivot이 더 크면 증가
while(pivot >= arr[low]&&low<=right) //&& 이후는 정렬 범위 명확히 하기위한 조건식
low++;
// pivot이 더 작으면 감소
while(pivot <= arr[high]&& high>=(left+1))
high--;
if(low <= high)
Swap(arr,low,high);
}
Swap(arr,left,high);
return high; // 다음 partition 반환
}
○ 퀵 정렬 Quick Sort Function
void QuickSort(int arr[],int left,int right){
// left 가 right 보다 작을때까지 호출하는 이유는 호출시 pivot의 +-1 씩하기 때문,,,
if(left<=right){
int pivot = Partition(arr,left,right);
QuickSort(arr,left,pivot-1); // pivot 을 기점으로 재귀 호출 (좌)
QuickSort(arr,pivot+1,right); // pivot 을 기점으로 재귀 호출 (우)
}
}
● 피벗 선택에 대한 논의
가급적 중간에 해당하는 값이 선택되면 좋은 성능을 보인다.
배열의 3개 값중 중간값을 골라서 PIVOT 으로 선정하면 성능적으로 좋은 모습을 보임.
● 퀵 정렬: 성능평가(최선의 경우)
○ 최상 및 평균의 경우(Best & Average Case)
PIVOT 을 기점으로 순환 호출의 깊이 : log2n
n번의 비교연산이 필요하다.(left 와 right) : n
big-oh : O(nlog2n)
○ 최악의 경우(Worst Case)
둘로 나뉘는 횟수가 : 약 n
매 단계별 비교 연산의 횟수 : 약 n
big-oh : O(n^2)
'DataStructure' 카테고리의 다른 글
(자료구조) AVL 트리의 이해와 구현 (0) | 2024.06.21 |
---|---|
(자료구조) 이진 탐색 트리(BST) (0) | 2024.06.15 |
(자료구조) 병합 정렬(Merge Sort) (1) | 2024.06.07 |
(자료구조) 간단한 정렬 알고리즘 3가지 (버블 정렬,선택 정렬,삽입 정렬) (0) | 2024.06.01 |
(자료구조) Heap 의 개념 및 구현 (0) | 2024.05.31 |