나의개발일지

정렬 알고리즘 .in python 본문

언어/Python

정렬 알고리즘 .in python

아. 이렇게 하면 될거 같은데.. 2023. 11. 16. 17:30
728x90

정렬 알고리즘

- 정렬이란 데이터를 특정한 기준에 따라 순서대로 나열하는것이다.

- 일반적으로 문제 상황에 따라서 적절한 정렬 알고리즘이 공식처럼 사용한다.

 


1. 선택 정렬

- 처리되지 않은 데이터 중에서 가장 작은 데이터를 선택해 맨 앞에 있는 데이터와 바꾸는 것을 반폭하는 정렬

- 매번 탐색 범위 만큼 선형탐색한다 2중 반복문으로 구현한다.

 

 

- 선택 정렬은 N번 만큼 가장 작은 수를 찾아서 맨 앞으로 보낸다

- 구현 방식에 따라서 사소한 오차는 있을 수 있지만, 전체 연산 횟수는 다음과 같다.

 

N + (N -1) + (N-2) + … + 2

 

- 이는 (N^2 + N-2) /2 로 표현할 수 있는데, 빅오 표기법에 의해 O(N^2)이라고 작성한다


선택 정렬 코드

array = [7, 5, 9, 0, 3, 1, 6, 2, 4, 8]

for i in range(len(array)):
	min_index = i 
	for j in range(i + 1, len(array)):
		if array[min_index] > array[j]:
			min_index = j
	array[i], array[min_index] = array[min_index], array[i] 

print(array)

 


2. 삽입 정렬

- 처리되지 않은 데이터를 하나씩 골라 적절한 위치에 삽입한다

- 선택 정렬에 비해 구현 난이도가 높은편이지만, 일반적으로 더 효율적으로 동작한다

 

- 삽입 정렬의 시간 복잡도는 O(N^2), 선택 정렬과 마찬가지로 반복문이 두 번 중첩되어 사용

- 삽입 정렬은 현재 리스트의 데이터가 거의 정렬되어 있는 상태라면 매우 빠르게 동작

- 최선의 경우 O(N) = 이미 정렬되어있는 경우


삽입 정렬 코드

array = [7, 5, 9, 0, 3, 1, 6, 2, 4, 8]

for i in range(1,len(array)):
    for j in range(i, 0, -1):
        if array[j] < array[j-1]:
            array[j-1], array[j] = array[j], array[j-1]
            print(array, i , j)
        else:
            print(array)
            break

print(array)

 


3. 퀵 정렬(Quick Sort)

- 기준 데이터를 설정하고 그 기준보다 큰 데이터와 작은 데이터의 위치를 바구는 방법이다.

- 일반적인 상황에서 가장 많이 사용되는 정렬 알고리즘 중 하나이다.

- 병합 정렬과 더불어 대부분의 프로그래밍 언어의 정렬 라이브러리의 근간이 되는 알고리즘이다.

- 가장 기본적인 퀵 정렬은 첫 번째 데이터를 기준 데이터(pivot)로 설정한다.

 

- 이상적인 경우 분할이 절반씩 일어난다면 전체 연산 횟수 O(NlogN)가 기대된다.

- 하지만 최악의 경우 이미 정렬된 배열일때 O(N^2)의 시간 복잡도가 기대된다.

- 한번 할때마다 왼쪽의 하나뺴고 오른쪽 나머지가 남는다.


퀵정렬 코드

def quick_sort(array, start, end):
    if start >= end:
        return

    pivot = start
    left = start + 1
    right = end

    while(right >= left):
        while(left <= end and array[pivot] >= array[left]):
            left += 1
        while(right > start and array[pivot] <= array[right]):
            right -= 1

        if (left > right):
            array[pivot], array[right] = array[right], array[pivot]
        else:
            array[left], array[right] = array[right], array[left]

        quick_sort(array, start, right-1)
        quick_sort(array, right+1, end)

 

퀵정렬 코드 .in Python (파이썬 라이브러리 이용)

def quick_sort2(array):
    if len(array) <= 1:
        return array
        
    pivot = array[0]
    tail = array[1:]

    left_side = [x for x in tail if x <= pivot]
    right_side = [x for x in tail if x > pivot]

    print(left_side, "left")
    print(right_side, "right")
    array = quick_sort2(left_side) + [pivot] + quick_sort2(right_side)
    return array

 


4. 계수 정렬

- 특정한 조건이 부합할 때만 사용할 수 있지만 매우 빠르게 동작하는 정렬 알고리즘

    > 계수 정렬은 데이터의 크기 범위가 제한되어 정수 형태로 표현할 수 있을 때 사용 가능

- 데이터의 개수가 N, 데이터(양수) 중 최댓값이 K일때 최악의 경우에도 수행시간 O(N + K)를 보장

 

pred. 가장 작은 데이터부터 가장 큰 데이터까지의 범위가 모두 담길 수 있도록 리스트를 생성

 

 

- 계수 정렬의 시간 복잡도와 공간 복잡도는 모두 O(N + K)

- 계수 정렬은 때에 따라서 심각한 비효율성을 초래할 수 있음

    > 데이터가 0과 999,999로 단 2개만 존재하는 경우

- 계수 정렬은 동일한 값을 가지는 데이터가 여러개 등장할 때 효과적으로 사용할 수 있다.

    > 성적의 경우 100점을 맞은 학생이 여러 명일 수 있기 때문에 계수 정렬이 효과적

 


계수 정렬 코드

array = [7, 5, 9, 0, 3, 1, 6, 2, 9, 1, 4, 8, 0, 5, 2]

count = [0] * (max(array)+1)

for i in range(len(array)):
    count[array[i]] += 1

print(count)

for i in range(len(count)):
    for j in range(count[i]):
        print(i, end=' ')

정렬 알고리즘 비교

 

정렬 알고리즘 평균 시간 복잡도 공간 복잡도 특징
선택 정렬 O(N^2) O(N) 아이디어가 매우 간단하다.
삽입 정렬 O(N^2) O(N) 데이터가 거의 정렬되어 있을 때는 가장 빠르다.
퀵 정렬 O(NlogN) O(N) 대부분의 경우에 가장 적합하며, 충분히 빠르다.
계수 정렬 O(N + K) O(N + K) 데이터의 크기가 한정되어 있는 경우에만 사용이 가능하지만 매우 빠르게 동작한다.

 

728x90
반응형