ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 셸 정렬
    Algorithm 2022. 1. 31. 13:59

    정의

     

    셸 정렬(shell sort)은 단순 삽입 정렬의 장점을 살리고 단점은 보완하여 더 빠르게 정렬하는 알고리즘이다.

     

    단순 삽입의 특징

    - 장점 : 이미 정렬을 마쳤거나 정렬이 거의 끝나가는 상태에서는 속도가 아주 빠르다.

    - 단점 : 삽입할 위치가 멀리 떨어져 있으면 이동 횟수가 많아진다.

     

    셀 정렬은 먼저 정렬할 배열의 원소를 그룹으로 나눠 각 그룹별로 정렬을 수행한다. 그 후 정렬된 그룹을 합치는 작업을 반복하여 원소의 이동 횟수를 줄인다.

     

    위의 배열은 먼저 서로 4칸씩 떨어진 원소를 꺼내어 4개의 그룹으로 나누고 그룹별로 정렬한다. 이런 방법을 '4 - 정렬'이라고 한다. 아직 정렬을 마치지 않았지만 정렬의 상태와 가까워졌다. 

     

     

    이어서 2칸 떨어진 원소를 모두 꺼내 '2 - 정렬'을 진행한다.

     

     

    이후 '1 - 정렬'을 적용하면 오른차순 정렬이 완료된다. 

    삽입 정렬에 비해 정렬 횟수는 늘어나지만 전체적으로 원소의 이동 횟수가 줄어들어 효율적이다.

     

    <code>

    더보기
    def shell_sort(a):
        n = len(a)
        h = n // 2 # h의 초깃값은 배열의 절반값이다 while문을 반복할 때마다 2배씩 줄어든다.
        while h > 0:
            for i in range(h, n):   # 5~12행은 단순 삽입 정렬을 수행하는 과정이다. 다른점은 주목 원소와 비교 원소가 h개만큼 떨어져 있다는 것.
                j = i - h
                tmp = a[i]
                while j >= 0 and a[j] > tmp:
                    a[j + h] = a[j]  # 한 칸 뒤로 
                    j -= h
                a[j + h] = tmp
            h //= 2
            
    if __name__ == '__main__':
        print('셸 정렬을 수행합니다.')
        num = int(input('원소 수를 입력하세요 : '))
        x = [None] * num
        
        for i in range(num):
            x[i] = int(input(f'x[{i}]: '))
            
        shell_sort(x)
        
        print('오름차순으로 정렬했습니다.')
        for i in range(num):
            print(f'x[{i}] = {x[i]}')

     

     

    부분 집합으로 나누는 h의 초깃값은 전체 배열의 절반값이다. while 문을 반복할 때마다 다시 2로 나눈 값으로 업데이트한다. 즉, 원소 수가 8이면 4, 2, 1순으로 변화하고, 7이면 3, 1순으로 변한다.

     

    셸 정렬의 시간 복잡도는 O(n^1.25)이고 단순 정렬의 시간 복잡도인 O(n^2)보다 매우 빠르다. 그러나 셸 정렬 알고리즘은 이웃하지 않고 떨어져 있는 원소를 서로 교환하므로 안정적이지 않다.

     

     

    'Algorithm' 카테고리의 다른 글

    병합 정렬  (0) 2022.02.06
    퀵 정렬  (0) 2022.01.31
    단순 선택 정렬 / 단순 삽입 정렬  (0) 2022.01.29
    버블 정렬  (0) 2022.01.29
    재귀 알고리즘 분석  (0) 2022.01.28
Designed by Tistory.