ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 퀵 정렬
    알고리즘/정렬 2021. 12. 25. 00:07
    728x90

     

    퀵 정렬 : 하나의 큰 문제를 두 개의 작은 문제로 분할하는 정렬 알고리즘이다.

    특정한 값을 기준(pivot)으로 큰 숫자와 작은 숫자를 선택해 서로 교환한 뒤 배열을 반으로 나눈다. 일반적으로 pivot은 첫번째 원소부터 설정된다.

    Ex)

    pivot을 기준으로 왼쪽에선 큰값을 찾고, 오른쪽에선 작은 값을 찾는다.

     

    3 7 8 1 5 9 6 10 2 4

    3 2 8 1 5 9 6 10 7 4

    3 2 1 8 5 9 6 10 7 4

     

    (작은 값의 인덱스가 큰 값의 인덱스보다 작아 엇갈릴 때 작은 값과 pivot이 교환되어 첫번째 분할이 일어남.)

     

    1 2 3 8 5 9 6 10 7 4

     

    (3을 기준으로하여 왼쪽의 집합과 오른쪽의 집합에서 각각 pivot이 정해진 뒤 정렬을 수행함.)

     

    위의 과정 반복

     

    1 2 3 8 5 4 6 10 7 9

    1 2 3 8 5 4 6 7 10 9

    1 2 3 7 5 4 6 8 10 9

    1 2 3 6 5 4 7 8 10 9

    ~

    1 2 3 4 5 6 7 8 9 10

     

    정렬을 수행했을 때 왼쪽과 오른쪽이 계속 나눠진다.

     

    시간복잡도 : 선택, 버블, 삽입 정렬에 비해 훨씬 빠른 분할 정복 알고리즘으로 평균적인 시간복잡도는 O(N*logN)이다.데이터의 개수가 n개이고, 반씩 분할되므로 O(N*logN)이 나오게 된다.

     

    그러나, 최악의 경우 O(N^2)이 나오는데 이미 정렬이 되어있는 경우 pivot을 설정하고 분할이 되지않으므로(엇갈릴 때 계속 자기 자신과 스왑하므로) 연산 횟수가 N^2/2번이 나오게 된다. 이러한 경우 삽입 정렬을 사용하는 것이 속도가 빠르다.

     

    #include <iostream>
    
    using namespace std;
    
    int n = 10;
    int data[10] = {1, 10, 5, 8, 7, 6, 4, 3, 2, 9};
    
    void Quick_Sort(int* data, int start, int end) {
    	if(start >= end) // 원소가 1개인 경우 
    		return; 
    		
    	int pivot = start; // pivot은 처음에 첫번째 원소로 설정됨.
    	int i = start + 1; // 왼쪽 출발 지점 
    	int j = end; // 오른쪽 출발 지점 
    	int temp;
    	
    	while(i<=j) { // 엇갈릴 때까지 반복 
    		while(data[i]<=data[pivot]) // 피봇 값보다 큰 값을 만날때까지 오른쪽 이동
    			i++;
    		while(data[j]>=data[pivot] && j > start) // 피봇 값보다 작은 값을 만날때까지 왼쪽 이동
    			j--; 
    		
    		if(i>j) { // 현재 엇갈린 상태면 피봇 값과 교체 
    			temp = data[j];
    			data[j] = data[pivot];
    			data[pivot] = temp; 
    		}
    		else {
    			temp = data[i];
    			data[i] = data[j];
    			data[j] = temp;
    		}
    	}
    	// 엇갈렸을 때 스왑한 후 분할이 일어나고 다시 왼쪽과 오른쪽에서 퀵정렬이 수행된다. 
    	Quick_Sort(data, start, j-1);  
    	Quick_Sort(data, j+1, end);
    }
    
    int main() {
    	Quick_Sort(data, 0, n-1);
    	for(int i = 0; i<n; i++) {
    		cout<<data[i]<<' ';
    	}
    }
    728x90

    '알고리즘 > 정렬' 카테고리의 다른 글

    힙 정렬  (0) 2021.12.25
    병합 정렬  (0) 2021.12.25
    삽입 정렬  (0) 2021.12.24
    버블 정렬  (0) 2021.12.24
    선택 정렬  (0) 2021.12.24

    댓글

Designed by Tistory.