algorithm/theory

쉘 정렬.

qkqhxla1 2016. 6. 11. 18:29

정렬 방법론.

1. h값에 따라 리스트를 새로 만든다. 리스트의 길이는 15이고 h=4일경우 ex) [1번째,5번째,9번째,13번째],[2번째,6번째,10번째,14번째] .. h=13일 경우는 [1번째,14번째],[2번째,15번째] 두개의 리스트가 나온다.(리스트 길이 15인 경우.)

2. h값은 3*h+1로 정한다. h=1,4,13,40,121,264...이런 순으로 만들어지는데 리스트의 길이보다 작으면서 가장 큰 값을 선택한다. 리스트의 길이가 15면 h=13을 고른다.

3. 정렬시 h=13으로 정렬했으면 그다음으로 작은 h=4로 정렬한다.(그다음은 h=1)

4. 각각 새로 만들어진 작은 리스트들은 각각 삽입 정렬을 수행시킨다.

5. h=1일경우 그냥 삽입 정렬을 수행한다.


특징.

1. 정렬이 된 경우가 유리한 삽입정렬의 특징을 이용해서 성능을 개선시켰다.

2. h=3*h+1로 하는 이유는 이게 효율적이라고 한다...



좋은 그림이 없어서 책의 예제를 빌려옴.

리스트 = [3, 1, 12, 4, 10, 13, 15, 5, 2, 7, 9, 6, 8, 11, 14]가 있다고 할 경우

h=4리스트는 

[3,10,2,8],[1,13,7,11],[12,15,9,14],[4,5,6] 이 만들어진다.

이 각각을 삽입정렬하면 [2,3,8,10],[1,7,11,13],[9,12,14,15],[4,5,6] 이 되는데 

다시 리스트를 만들면

[2,1,9,4,3,7,12,5,8,11,14,6,10,13,15] 가 된다.

h=4를 예로들었는데 이전에 리스트의 길이가 15므로 h=13에 대해서 정렬을 먼저 해야 한다.


시간 복잡도는 O(n^1.25) 이다.(앞에 것들과 비교해서 빠른 편)


# -*- encoding: cp949 -*-
import time
import random
 
N = 10000
def swap(a,i,j):
    a[i],a[j] = a[j],a[i]
 
def CheckSort(a,n):
    Sorted = True
    for i in range(n):
        if a[i] > a[i+1]:
            Sorted = False
        if not Sorted:
            break
    if Sorted: print '정렬 완료.'
    else: print '정렬 오류 발생.'
 
def ShellSort(a,n):
    h = 1
    while h<n:
        h = 3*h+1
    while h>0:
        for i in range(h+1,n+1):
            v = a[i]
            j = i
            while j>h and a[j-h] > v:
                a[j] = a[j-h]
                j -= h
            a[j] = v
        h /= 3

def main():
    a = [random.randint(1,65536) for i in range(0,N+1)] #랜덤한 10000개의 데이터
    a[0] = -1
    start_time = time.time()
    ShellSort(a,N)
    print '(랜덤)쉘 정렬의 실행 시간 (N = {} ) : {}'.format(N,time.time()-start_time)
    CheckSort(a,N)

    a = [i for i in range(0,N+1)] #정렬된 10000개의 데이터
    a[0] = -1
    start_time = time.time()
    ShellSort(a,N)
    print '(최고)쉘 정렬의 실행 시간 (N = {} ) : {}'.format(N,time.time()-start_time)
    CheckSort(a,N)
 
    a = [i for i in range(N,-1,-1)] #최악의 경우의 10000개의 데이터
    a[0] = -1
    start_time = time.time()
    ShellSort(a,N)
    print '(최악)쉘 정렬의 실행 시간 (N = {} ) : {}'.format(N,time.time()-start_time)
    CheckSort(a,N)
 
if __name__=='__main__':
    main()


'algorithm > theory' 카테고리의 다른 글

합병 정렬.  (0) 2016.06.13
퀵 정렬.  (0) 2016.06.12
삽입 정렬.  (0) 2016.06.11
버블 정렬.  (0) 2016.06.10
선택 정렬.  (0) 2016.06.10