1 / 38

이 완 직 ( wjlee@pnu.ac.kr ) 2010 년 1 학기

9 장 . 정렬 (Sorting) 1 절 . 정렬 2 절 . 버블 정렬 3 절 . 선택 정렬 4 절 . 삽입 정렬 5 절 . 쉘 정렬 6 절 . 퀵 정렬 7. 합병 정렬 8. 기수 정렬 9. 히프 정렬. 이 완 직 ( wjlee@pnu.ac.kr ) 2010 년 1 학기. 1. 정렬. 내부 정렬 교환 방식 : 키를 비교하고 교환하여 정렬하는 방식 ( 선택 정렬 , 버블 정렬 , 퀵 정렬 )

malana
Télécharger la présentation

이 완 직 ( wjlee@pnu.ac.kr ) 2010 년 1 학기

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 9장. 정렬(Sorting) 1절. 정렬 2절. 버블 정렬 3절. 선택 정렬 4절. 삽입 정렬 5절. 쉘 정렬 6절. 퀵 정렬 7. 합병 정렬 8. 기수 정렬 9. 히프 정렬 이 완 직 (wjlee@pnu.ac.kr) 2010년 1학기

  2. 1. 정렬 • 내부 정렬 • 교환 방식: 키를 비교하고 교환하여 정렬하는 방식 (선택 정렬, 버블 정렬, 퀵 정렬) • 삽입 방식: 키를 비교하고 삽입하여 정렬하는 방식 (삽입 정렬, 쉘 정렬) • 병합 방식: 키를 비교하고 병합하여 정렬하는 방식 (2-way 병합, n-way 병합) • 분배 방식: 키를 구성하는 값을 여러 부분집합에 분배하여 정렬 (기수 정렬) • 선택 방식 : 이진 트리를 사용하여 정렬하는 방식 (히프 정렬, 트리 정렬) • 외부 정렬 • 병합 방식: 파일을 부분 파일로 분리하여 각각을 내부 정렬 방법으로 정렬하여 병합하는 정렬 방식(2-way 병합, n-way 병합)

  3. 2. 버블 정렬 • 인접한 원소끼리 비교하여 교환 • 오름차순으로 정렬하려면 인접한 요소끼리 비교하여 큰 값을 뒤로 보낸다.

  4. 2단계 3단계 4단계 5단계 2. 버블 정렬

  5. 6단계 7단계 2. 버블 정렬

  6. [예제 9-1] 버블 정렬

  7. 3. 선택 정렬(selection sorting) • 가장 작은 카드를 뽑아서 제일 앞에 놓고 그 다음 작은 카드를 뽑아서 두 번째 위치에 놓는 식의 작업을 반복하여 정렬한다. • 방법(배열 크기 7, 오름차순 정렬 가정) • 기준 위치값인 base는 0부터 5까지 변경된다. • 비교 대상은 기준위치보다 하나 큰 값에서 배열의 마지막 요소의 위치인 6까지 변경된다. • 기준위치의 값과 비교대상의 대소 관계를 물어보고 비교 대상의 값이 작으면 해당 위치의 인덱스 값을 변수(min)에 저장해둔다.

  8. [예제 9-2] 선택 정렬

  9. 4. 삽입 정렬 • 이미 정렬이 된 부분에 새로운 키를 적절한 장소에 삽입하는 동작을 반복적으로 하는 정렬 방법 • 절차 • 초기 상태 • 첫 번째 원소는 정렬되어 있는 부분 집합 S로 생각하고 나머지 원소들은 정렬되지 않은 원소들의 부분 집합 U로 생각

  10. 4. 삽입 정렬 • U의 첫 번째 원소 Y를 S의 마지막 원소 G와 비교하면 (G < Y)이고 더 이상 비교할 S의 원소가 없으므로 제자리에 둔다. • U의 첫 번째 원소 B를 S의 마지막 원소 Y와 비교하면 (B < Y)이므로 원소 Y의 앞자리 원소 G와 비교한다. (B < G)이므로 원소 B는 원소 G의 앞자리가 된다.

  11. 4. 삽입 정렬 • U의 첫 번째 원소 R을 S의 마지막 원소 Y와 비교하면 (R < Y)이므로 원소 Y의 앞자리 원소 G와 비교하고 (R > G)이므로 G와 Y사이에 R을 삽입한다. • U의 첫 번째 원소 P를 S의 마지막 원소 Y와 비교하면 (P < Y)이므로 그 앞자리 원소 R과 비교한다. (P < R)이므로 다시 그 앞자리 원소 G와 비교한다. (P > G)이므로 원소 G와 R 사이에 삽입한다.

  12. 4. 삽입 정렬 • U의 첫 번째 원소 C를 S의 마지막 원소 Y와 비교하면 (C < Y)이므로 그 앞자리 원소 R과 비교한다. (C < R)이므로 그 앞자리 원소 P와 비교한다. (C < P)이므로 다시 그 앞자리 원소 G와 비교하는데, (C < G)이므로 그 앞자리 원소 B와 비교하여 (C > B)이므로 원소 B와 G사이에 삽입한다.

  13. 4. 삽입 정렬 • U의 첫 번째 원소W를 S의 마지막 원소 Y와 비교하면 (W < Y)이므로 제자리에 둔다.

  14. [예제 9-3] 삽입 정렬

  15. 5. 쉘 정렬 • 삽입 정렬이 어느 정도 정렬된 배열에 대해서는 대단히 빠른 것에 착안한 방법 -> 쉘 정렬은 삽입 정렬보다 빠르다 • 전체 리스트를 일정 간격의 부분 리스트로 나누고 부분 리스트를 정렬하기 때문에 요소들이 멀리 떨어진 위치로도 이동할 수 있다. • 일정한 간격(interval)으로 떨어져 있는 자료들끼리 부분집합을 구성 • 각 부분집합에 있는 원소들에 대해서 삽입 정렬을 수행하는 작업을 반복하면서 전체 원소들을 정렬

  16. 5. 쉘 정렬 • 원소의 개수가 8개이므로 매개변수 h는 4에서 시작한다. 간격이 4인 원소들을 같은 부분 집합으로 만들면 4개의 부분 집합이 만들어진다. • 각 부분 집합에 대한 삽입 정렬을 수행한다. {69, 16} {10, 8} {30, 31} {2, 22}

  17. 5. 쉘 정렬 • 이제 h를 2로 변경하고 다시 쉘 정렬을 수행한다. 간격이 2인 원소들을 같은 부분 집합으로 만들면 2개의 부분 집합이 만들어진다. • 각 부분 집합에 대한 삽입 정렬을 수행한다. {16, 30, 69, 31} {8, 2, 10, 22}

  18. 5. 쉘 정렬 • 이제 h를 1로 변경하고 다시 쉘 정렬 시작한다. 간격이 1인 원소들을 같은 부분 집합으로 만들면 1개의 부분 집합이 만들어진다 • 성능 분석 • h의 영향을 받기 때문에 성능 분석이 쉽지 않음 • 일반적인 복잡도는 O(n1.25) • 이전의 정렬 방법의 성능 O(n2)보다 개선된 정렬 방법

  19. [예제 9-4] 쉘 정렬

  20. 6. 퀵 정렬 • 버블 정렬이나 선택 정렬에 비하여 빠른 속도로 정렬을 수행 • 연속적인 분할을 하면서 정렬을 수행 • 축(Pivot)값을 중심으로 왼쪽은 이 축 값보다 작은 값으로, 오른쪽은 이 축 값보다 큰 값으로 재배열시킴 • 축을 기준으로 왼쪽과 오른쪽을 분할한 뒤 각 부분에 따로 축을 두고 축을 기준으로 왼쪽, 오른쪽에 축 값을 재배열한 후 또다시 분할함 • 이 과정을 분할의 크기가 1이 될 때까지 반복하면 전체적으로 정렬이 완료됨

  21. 6. 퀵 정렬 • Pivot: 6, left:0, right:5 • left를 증가시키면서 Pivot 값(37)보다 큰 값을 찾음 • right를 감소시키면서 Pivot 값(37)보다 작은 값을 찾음 • 값 45(left:0), 값 5(right:5): 교환 • 값 87(left:1), 값 35(right:3): 교환

  22. 6. 퀵 정렬 • 값 87(left:3), 10(right:2) => left가 right를 넘어감: 분할 완료 인식 • 분할 완료 시: 값 87(left:3)과 pivot(6)의 값(87)을 교환 • 이제 배열은 기존 축 값(37)을 기준으로 37보다 작은 왼쪽 영역과 37보다 큰 오른쪽 영역으로 분할됨. • 각 영역별 동일한 정렬 방법을 적용 • [left 영역] • Pivot:2, left:0, right:1 -> left:1, right:0 : left 값과 pivot 값 교환 • pivot:1(값 10)을 중심으로 두 영역이 또 나누어지나, 구간 크기가 1이므로 종료

  23. 6. 퀵 정렬 • [right 영역] • pivot:6(값 87), left:4, right:5 • left:6(값 87), right:5(값 45) => left가 right를 넘어감 • left 값 87과 pivot 값 87을 교환(동일) • 87 값을 기준으로 왼쪽 영역(개수 2개)와 오른쪽 영역(개수 0개)로 분할 • 오른쪽 영역의 개수가 0이므로 종료

  24. 6. 퀵 정렬 • [left 영역] • pivot:5, left:4, right:4 • left:4, right:4 => left가 right보다 크거나 같으면 분할 종료이므로 left 값 51과 pivot 값 45를 교환 • 45를 기준으로 영역 분할 • 왼쪽 영역 개수가 0, 오른쪽 영역 개수가 1이므로 정렬 종료

  25. 6. 퀵 정렬 • 성능 분석 • pivot 값 선택에 따라 성능이 달라짐 • pivot 값으로 [left 영역], [right 영역]으로 정확히 n/2 씩 이등분되면 성능이 최대 • n개의 레코드에서 하나의 레코드를 위치시키는 데 소요되는 시간은 O(n) • 퀵정렬 시간을 T(n)으로 둘때, T(n) <= cn + 2T(n/2) <= cn + 2(cn/2 + 2T(n/4)) <= 2cn + 4T(n/4) … … <= cnlog2n + nT(1) = O(nlog2n) • 평균 정렬시간: O(nlog2n) • 최악의 정렬시간: O(n2)

  26. [예제 9-5] 퀵 정렬

  27. 7. 합병 정렬(merge sort) • 리스트를 두 개로 나누어 각각을 정렬한 다음 다시 하나로 합치는 방법으로, 분할 정복(divide and conquer)기법에 바탕 • 2-원 합병 정렬 • 분할(divide) : 입력 자료를 같은 크기의 부분 집합 2개로 분할 • 정복(conquer) : 부분집합의 원소들을 정렬한다. 부분집합의 크기가 충분히 작지 않으면, 순환호출을 이용하여 다시 분할 정복 기법을 적용한다. • 결합(combine) : 정렬된 부분집합들을 하나의 집합으로 통합한다.

  28. 7. 합병 정렬 • 분할 단계 • 합병 단계

  29. [예제 9-6] 합병 정렬

  30. 7. 합병 정렬 • 성능 분석 • 합병 정렬은 길이 n인 리스트를 균등 배분:logn개의 패스 • 각 패스 당 n개를 비교 합병: n개의 연산 • O(nlogn) • 배열을 사용할 경우, 각 패스에서 2n번의 레코드 이동 • 연결 리스트를 이용한 합병 정렬은 매우 우수한 정렬 기법

  31. 8. 기수 정렬(radix sort) • 버킷 정렬(bucket sort)이라고도 불리며, 분배 방식으로 정렬을 수행한다. • 정렬할 원소의 키 값에 해당하는 버킷에 원소를 분배하였다가, 버킷의 순서대로 원소를 꺼내는 방법을 반복한다.

  32. 8. 기수 정렬 • 키값의 일의 자리에 대해서 기수 정렬을 수행한다. • 정렬할 원소의 일의 자리값에 따라서 순서대로 버킷에 분배한다. • 버킷에 분배된 원소들을 순서대로 꺼내어 저장한다.

  33. 8. 기수 정렬 • 키 값의 십의 자리에 대해서 기수 정렬을 수행한다. • 정렬할 원소의 십의 자리값에 따라 순서대로 버킷에 분배한다. • 버킷에 분배된 원소들을 순서대로 꺼내어 저장한다.

  34. [예제 9-7] 기수 정렬

  35. 8. 기수 정렬 • 성능 분석 • O(n)의 성능 • 지금까지의 정렬 기법들의 성능인 O(nlogn)의 한계를 깰 수 있는 유일한 정렬 방법 • 기수 정렬의 단점 • 정렬될 레코드들의 키가 동일한 길이를 가지는 숫자나 문자열일 경우에만 가능한 정렬 기법

  36. 9. 히프 정렬 • 히프에서는 항상 가장 큰 원소가 루트 노드가 되고 삭제 연산을 수행하면 항상 루트 노드의 원소를 삭제하여 반환된다. • 내림차순으로 정렬하려면 최대 히프에 대해서 원소의 개수만큼 삭제 연산을 수행하고 • 오름차순으로 정렬하려면 최소 히프에 대해서 원소의 개수만큼 삭제 연산을 수행한다. • 수행 방법 ❶ 정렬할 원소들을 입력하여 최대 히프 구성한다. ❷ 히프에 대해서 삭제 연산(히프 트리의 루트 노드를 출력)을 수행하여 얻은 원소를 마지막 자리에 배치한다. ❸ 나머지 노드들로 새로운 히프을 만드는 과정을 반복한다. ❹ ❷, ❸의 과정을 모든 레코드가 제거될 때까지 반복한다.

  37. [예제 9-8] 히프 정렬

  38. 9. 히프 정렬 • 성능 분석 • 히프에 삽입하거나 삭제할 때, O(logn) 소요 • 요소의 개수가 n개 이므로 전체 O(nlogn)의 시간이 소요 • 히프 정렬은 자료의 전체 정렬 시보다, 가장 큰(또는 작은) 값 몇 개만 필요할 경우 매우 유용한 기법

More Related