9장. 정렬 알고리즘 정렬 알고리즘 학습목표 가장 많이, 그리고 가장 잘 알려진 알고리즘 방법과 효율 빅 오 기호로 분석

Slides:



Advertisements
Similar presentations
10-7 부동소수점 (Floating-Point) 계산  컴퓨터에서 숫자를 표기하는 방법  가수 (Fraction) : 부호화된 고정소수점 숫자 지수 (Exponent) : 소수점의 위치를 표시 ( 예 )10 진수 를 표기하면 Fraction Exponent.
Advertisements

6 장. printf 와 scanf 함수에 대한 고찰 printf 함수 이야기 printf 는 문자열을 출력하는 함수이다. – 예제 printf1.c 참조 printf 는 특수 문자 출력이 가능하다. 특수 문자의 미 \a 경고음 소리 발생 \b 백스페이스 (backspace)
1. 2 차원 배열  배열은 동일한 데이터 유형으로 여러 개의 변수를 사용할 경우 같은 이 름으로 지정하여 간편하게 사용할 수 있도록 하는 것으로서 앞에서 1 차원 배열을 공부하였습니다.  2 차원 배열은 바둑판을 생각하면 되며, 1 차원 배열에서 사용하는 첨자를 2.
알고리즘 기본 개념 정렬 알고리즘 탐색 알고리즘 알고리즘 복잡도.
2장. 프로그램의 기본 구성. 2장. 프로그램의 기본 구성 2-1"Hello, World!" 들여다 보기 /* Hello.c */ #include int main(void) { printf("Hello, World! \n"); return 0;
연결리스트(linked list).
제 9 장 구조체와 공용체.
컴퓨터 프로그래밍 기초 [Final] 기말고사
Chapter 10. 정렬 Chapter 10-1: 단순한 정렬 알고리즘.
윤성우의 열혈 C 프로그래밍 윤성우 저 열혈강의 C 프로그래밍 개정판 Chapter 12. 포인터의 이해.
테이블 : 데이터베이스를 구성하는 요소로 같은 성격에 정보의 집합체. 레코드 : 하나의 정보를 가지고 있는 컬럼의 집합체
정보보안 프로젝트 (Sort Algorithm) 학 부 : 컴퓨터 정보공학부, 네트워크 정보 공학부
UNIT 07 Memory Map 로봇 SW 교육원 조용수.
5장. 참조 타입.
Internet Computing KUT Youn-Hee Han
P150 문제를 프로그래밍 할 것 Source file (헤더파일포함), 실행화면 (학번_이름_1.txt)
빠른정렬(Quick Sort) – 개요 (1/2)
Heesang kim PL/SQL 3 Heesang kim.
11장. 포인터 01_ 포인터의 기본 02_ 포인터와 Const.
SqlParameter 클래스 선문 비트 18기 발표자 : 박성한.
6장. printf와 scanf 함수에 대한 고찰
프로그래밍 랩 – 7주 리스트.
11장. 1차원 배열.
CHAP 9: 정렬 (part 2) 순천향대학교 컴퓨터학부 하 상 호.
6. 합병 정렬 합병 정렬 (Merge Sorting)
제 8 장 정렬.
C#.
13. 연산자 오버로딩.
JA A V W. 03.
프로그래밍 개요
어서와 C언어는 처음이지 제14장.
인터넷응용프로그래밍 JavaScript(Intro).
박성진 컴퓨터 프로그래밍 기초 [09] 배열 part 1 박성진
CHAP 9: 정렬 순천향대학교 컴퓨터학부 하 상 호.
자료구조: CHAP 7 트리 –review 순천향대학교 컴퓨터공학과 하 상 호.
Java의 정석 제 5 장 배 열 Java 정석 남궁성 강의 의
Quiz #7 다음 수들을 합병 정렬과 퀵 정렬 알고리즘을 이용하여 오름 차순으로 정렬하였을 때, 데이터 이동 회수를 각각 구하라. 여러분은 정렬 과정을 단계별로 보이면서 이동 회수를 추적해야 한다. 단, 퀵 정렬시에 피봇으로 배열의 왼쪽 첫 번째 원소를 선택한다. 5.
24장. 파일 입출력.
Chapter6 : JVM과 메모리 6.1 JVM의 구조와 메모리 모델 6.2 프로그램 실행과 메모리 6.3 객체생성과 메모리
컴퓨터 프로그래밍 기초 - 10th : 포인터 및 구조체 -
컴퓨터 프로그래밍 기초 - 8th : 함수와 변수 / 배열 -
5강. 배열 배열이란? 배열의 문법 변수와 같이 이해하는 배열의 메모리 구조의 이해 레퍼런스의 이해 다차원 배열
문자열 컴퓨터시뮬레이션학과 2015년 봄학기 담당교수 : 이형원 E304호,
계산기.
Canary value 스택 가드(Stack Guard).
균형이진탐색트리 이진 탐색(binary search)과 이진 탐색 트리(binary search tree)와의 차이점
알고리즘 알고리즘이란 무엇인가?.
데이터 동적 할당 Collection class.
4장. 데이터 표현 방식의 이해. 4장. 데이터 표현 방식의 이해 4-1 컴퓨터의 데이터 표현 진법에 대한 이해 n 진수 표현 방식 : n개의 문자를 이용해서 데이터를 표현 그림 4-1.
Chapter 1 단위, 물리량, 벡터.
DA :: 퀵 정렬 Quick Sort 퀵 정렬은 비교방식의 정렬 중 가장 빠른 정렬방법이다.
5장. 선택 알고리즘.
빠른정렬(Quick Sort) – 개요 (1/2)
7주차: Functions and Arrays
쉽게 배우는 알고리즘 2장. 점화식과 점근적 복잡도 분석
Chapter 10 데이터 검색1.
CHAP 9: 정렬 순천향대학교 컴퓨터학부 하 상 호.
TVM ver 최종보고서
컴퓨터 프로그래밍 기초 - 9th : 배열 / 포인터 -
트리 (Logical) Data Structures Linear list Tree Graph Linear structures
제 4 장 Record.
제 29 강 스트링(string) 다루기 s a i s . s T i h t g r i n.
어서와 C언어는 처음이지 제21장.
 6장. SQL 쿼리.
빠른정렬(Quick Sort) – 개요 (1/2)
C++ Espresso 제15장 STL 알고리즘.
7 생성자 함수.
6 객체.
BoardGame 보드게임 따라가기.
2019 2학기 9장 배열과 포인터 1. 주소, 주소연산자(&) 2. 포인터, 역참조연산자(*) 3. 배열과 포인터.
Presentation transcript:

9장. 정렬 알고리즘 정렬 알고리즘 학습목표 가장 많이, 그리고 가장 잘 알려진 알고리즘 방법과 효율 빅 오 기호로 분석 방법과 효율  빅 오 기호로 분석 학습목표 정렬 알고리즘의 분류방법을 이해한다. 정렬 알고리즘 별로 작동원리에 대해 이해한다. 정렬 알고리즘 별로 효율분석 방법을 이해한다. 정렬 알고리즘에 따라 효율을 개선하기 위한 방법을 이해한다.

정렬의 분류 정렬 오름차순, 내림차순 정렬의 대상 = 레코드 정렬의 기준 = 정렬 키(Sort Key) 필드 오름차순: 키 크기가 증가하는 순 내림차순: 키 크기가 감소하는 순

정렬의 분류 내부정렬, 외부정렬 내부정렬 정렬대상을 한꺼번에 메인 메모리에 올릴 수 있을 때 외부정렬 정렬대상을 한꺼번에 메인 메모리로 올릴 수 없을 때 메인 메모리와 보조 메모리 사이를 들락날락 하면서 정렬

정렬의 분류 안정 정렬(Stable Sorting)과 불안정 정렬(Unstable Sorting) 1차 키: 학점 2차 키: 학년 1차 키로 정렬하더라도 이전의 2차 키 정렬순서가 유지됨. 성명 학년 학점 주소지 김용태 1 C 대구 정지희 B 서울 유일근 A 박하영 3 전주 정건호 인천 김무성 수원 최석 4 용인 성명 학년 학점 주소지 김무성 3 A 수원 최석 4 용인 유일근 1 서울 박하영 B 전주 정지희 김용태 C 대구 정건호 인천 성명 학년 학점 주소지 유일근 1 A 서울 김무성 3 수원 최석 4 용인 정지희 B 박하영 전주 김용태 C 대구 정건호 인천

정렬의 분류 직접 정렬(Direct Sorting)과 간접 정렬(Indirect Sorting) 입력 직접정렬 간접정렬 인덱스 1 2 레코드 김모 90 박모 50 최모 70 인덱스 1 2 레코드 박모 50 최모 70 김모 90   1 2 인덱스   1 2 인덱스

선택정렬 가장 큰 것을 선택하여 가장 마지막 것과 스와핑 22 37 15 19 12 22 12 15 19 37 19 12 15

선택정렬의 효율 코드 9-1: 선택 정렬    void Selection(int A[ ], int N)            A는 배열이름, N은 정렬대상 레코드 수 {  for (int Last = N-1; Last >= 1; --Last)  마지막 인덱스를 왼쪽으로 이동하면서       {   int Largest = 0;                        일단 처음 것이 가장 크다고 보고         for (int Current=1; Current<=Last; Current++) 처음부터 마지막까지           {   if (A[Current] > A[Largest]) 현재 것이 더 크면                   Largest = Current;              현재 인덱스를 가장 큰 레코드의 인덱스로           }         int Temp = A[Last];                    이동을 위해 마지막 레코드를 잠시 저장           A[Last] = A[Largest];                  가장 큰 레코드를 마지막으로 이동           A[Largest] = Temp;                    마지막 것을 가장 큰 레코드 위치로 이동       }    } if 문: (N-1) + (N-2) + ... + 1 = (N-1)N/2 번 실행, 비교와 할당으로 구성 기타 할당문: 4(N-1) 효율: 2(N-1)N/2 + 4(N-1) = N2 + 3N - 4 = O(N2) 대략적 분석: 왼쪽 위의 삼각형 면적이 비교의 횟수임. O(N2/2) = O(N2)

이중 선택정렬 한 번의 스캔에 최대치와 최소치를 동시에 발견하고 스와핑 MinMax Sorting O(N2/2) = O(N2) 단계의 수가 반으로 감소 계수를 줄이는 노력   13 40 15 12 35 14 19 17 1단계 결과 2단계 결과 3단계 결과 4단계 결과

버블정렬 버블정렬

버블정렬 가장 큰 레코드가 한 칸씩 오른쪽 끝으로 떠올라 오는 정렬 한 쌍씩 비교하되 이전 쌍의 둘째 레코드가 다음 쌍의 첫 레코드가 되게 중복

버블정렬 단계 수 데이터 N개라면 버블 정렬의 단계 수는 대략 N. 어떤 단계에서 스와핑이 한번도 일어나지 않았다면 (이어지는 한 쌍끼리 모두) 정렬 완료된 것임. 코드 9-2: 버블 정렬 void Bubble(int A[ ], int N)   A는 배열이름, N은 정렬대상 레코드 수 {    bool Sorted = FALSE;    스와핑이 전혀 없는 단계에서 빠져나가기 위한 변수      for (int Pass = 1; (Pass < N) && (!Sorted); ++Pass)      {    Sorted = TRUE;        스와핑이 전혀 없다고 초기화            for (int Current=0; Current<N-Pass; ++Current)           {    if A[Current] > A[Current+1]   현재 것이 다음 것보다 크면                {    int Temp = A[Current];     스왑                        A[Current] = A[Current+1];                     A[Current+1] = Temp;                     Sorted = FALSE;      스왑이 한번이라도 일어나면 다음 단계로                ] 안쪽 루프 내부의 명령은 (N-1) + (N-2) + ... + 1 = (N-1)N/2 번 수행. 루프 내부의 비교문은 (N-1)N/2 번. 할당문 각각이 4 (N-1)N/2 번. 최종효율 (N-1)N/2 + 2(N-1)N = O(N2)

버블정렬, 선택정렬 단계 이미 정렬된 데이터 단계별로 가장 큰 것이 가장 오른쪽으로 이동한다는 점에서 동일 선택정렬은 가장 큰 것과 가장 오른쪽 것이 한번에 스와핑. 버블 정렬은 가장 큰 것이 한 칸씩 오른 쪽으로 이동 스와핑(교환, 복사)에 걸리는 시간 큰 레코드에 대해서 버블 정렬은 선택 정렬보다 불리 이미 정렬된 데이터 버블 정렬이 최선의 효율 1단계에서 끝남. (스와핑이 전혀 없음). O(N)의 효율 선택 정렬은 여전히 O(N2)의 효율. 가장 큰 데이터인 마지막 데이터가 자기 자신과 스왑(Self Swap)

삽입정렬 왼쪽 정렬된 그룹을 점차 키워 간다. 1 단계:가장 왼쪽 첫 레코드 하나만 주목. 그 자체로 정렬 2 단계: 다음 레코드를 왼쪽 것과 비교. 37은 22보다 크므로 그대로 둠. 3 단계: 15는 37의 왼쪽으로 가야한다. 풀 스왑: 삽입할 레코드가 계속적으로 왼쪽으로 옮김 하프 스왑: 삽입될 레코드는 단 한번만 움직임.

삽입정렬의 효율 코드 9-3: 삽입 정렬 효율 이미 정렬된 데이터에 대해 삽입 정렬은 최선의 효율 void Insertion(int A[ ], int N) { for (int Pick=1; Pick<N; ++Pick)  왼쪽부터 카드를 하나씩 집어내면서   {   int Current = Pick;                   집어낸 카드의 인덱스를 현재 인덱스로 int Temp = A[Pick];       for (; (Current > 0) && (A[Current-1]>Temp); --Current)           A[Current] = A[Current-1]; 집어낸 카드 보다 크면 오른쪽으로 이동       A[Current] = Temp;              집어낸 카드를 제 위치에 삽입 (하프 스왑)   } } 효율 안쪽 루프 명령문은 1 + 2 + ... + (N-1) = (N-1)N/2 번 실행 for 문 자체에 비교 2번, 할당 1번, for 문 내부에 할당이 1번 총 4(N-1)N/2 = 2(N-1)N = O(N2) 이미 정렬된 데이터에 대해 삽입 정렬은 최선의 효율 이미 정렬된 기존 사원 2000명, 신입사원 10명. 신입사원 파일을 기존사원 파일에 붙인 이후 삽입정렬. 2, 000명은 이미 정렬되어 있으므로 O(N) 신입사원은 최악의 경우 배열의 맨 앞까지 가면서 비교와 스왑. 이 작업은 10명에 불과하므로 10N의 시간. 따라서 전체적인 효율은 O(N) + O(10N) = O(N)

선택, 버블, 삽입 최악의 효율은 모두 O(N2)으로서 동일 버블 정렬과 삽입 정렬는 안정정렬 선택 정렬은 불안정 정렬 레코드들이 하나하나 순차적으로 이동(Shift)하기 때문에 원래의 순서가 유지 선택 정렬은 불안정 정렬 스왑(Swap)에 의해 단번에 멀리 떨어진 곳으로 이동   선택 정렬 버블 정렬 삽입 정렬 효율 O(N2) 안정정렬 No Yes

셸 정렬 셜 정렬

셸 정렬 삽입 정렬을 개선. 한 칸씩 이동하는 하는 대신 한번에 여러 칸 이동 4-정렬의 예 일련의 h-정렬 최종적으로는 1-정렬. 효율은 O(N3/2). 삽입 정렬의 O(N2)보다는 빠르지만 O(NlogN)보다는 느린 효율

합병 합병

합병 정렬된 그룹의 합병

합병함수 코드 9-4: 합병 함수 void Merge(dataType A[ ], int F, int Mid, int L)     F, Mid, L은 그룹 분리를 위한 인덱스 { dataType Temp[MAX];                          dataType의 배열 데이터를 가정    int First1 = F;  int Last1 = Mid;               F부터 Mid까지가 첫 그룹    int First2 = Mid + 1;  int Last2 = L;         (Mid+1)부터 L까지가 둘째 그룹    int Index = First1;    for (; (First1 <= Last1) && (First2 <= Last2); ++Index) 그룹 인덱스가 밖으로 안 나갈 동안   {    if (A[First1] < A[First2])          첫 그룹의 데이터가 작으면        {    Temp[Index] = A[First1];         임시 저장 공간에 복사              ++First1;                             포인터를 이동         }        else                                       둘째 그룹의 데이터가 작거나 같으면       {    Temp[Index] = A[First2];          임시 저장 공간에 복사            ++First2;                               포인터를 이동        }                             } for (; First1 <= Last1; ++First1, ++Index)    첫 그룹에 남은 데이터가 있으면          Temp[Index] = A[First1];                  순서대로 임시 저장 공간에 복사 for (; First2 <= Last2; ++First2, ++Index)     둘째 그룹에 남은 데이터가 있으면          Temp[Index] = A[First2];                  순서대로 임시 저장 공간에 복사 for (Index = F; Index <= L; ++Index)           임시 저장 공간의 데이터를          A[Index] = Temp[Index];                  원래 배열로 복사시킴 }

합병정렬 메인함수 코드 9-5: 합병 정렬의 메인함수 합병정렬 void MergeSort(int A[ ], int First, int Last) { if (First < Last)    {    int Middle = (First + Last) / 2;         MergeSort(A, First, Middle);         MergeSort(A, Middle+1, Last);         Merge(A, First, Middle, Last);       }    } 합병정렬 반 잘라서 왼쪽 재귀호출, 오른쪽 재귀호출. 결과를 합병 베이스 케이스로부터 빠져 나와 호출함수로 되돌아 오는 과정에서 Merge(A, First, Middle, Last) 즉, 합병에 의해 정렬

합병정렬 들어가고 나오기 합병정렬 들어가고 나오기

합병정렬의 효율 효율 O(NlgN) 호출의 단계 수가 lgN 각 단계별로 합병에 O(N)

삽입정렬과 합병정렬 효율 O(N2) 대 O(NlgN) 좋은 알고리즘은 슈퍼 컴퓨터보다 낫다. 삽입정렬 합병정렬 N=103 PC 순간적 2.8 시간 317년 수퍼 컴 1초 1.7 주 N=103 N=106 N=109 PC 순간적 1초 18분 수퍼 컴

쾌속 쾌속

쾌속정렬 합병정렬과 쾌속정렬 재귀호출의 순서에 유의 실제 정렬작업이 어디서 일어나는지 유의 MergeSort { MergeSort (Left);   MergeSort (Right);   Merge; } QuickSort { Partition;   QuickSort(Left);   QuickSort(Right);

쾌속정렬 코드 9-6: 파티션 함수 int partition(int A[ ], int first, int last) {  int low, high, pivotindex, p;    p = A[last];                            마지막 요소를 피벗으로    low = first;                           업 포인터를 처음으로    high = last-1;                          다운 포인터를 마지막 직전 요소로    while (low < high)                     크로스 오버가 없을 때까지    {  while (p > A[low]) low++;    피벗보다 크거나 같은 것 찾기       while (p < A[high]) high--;  피벗보다 작거나 같은 것 찾기       if (low < high)                      크로스 오버가 아니면           Swap(A, low, high);             작은 것과 큰 것을 스왑    }    Swap(A[low], A[last]);               업 포인터 레코드와 피벗 레코드를 스왑    return (low);                          피벗 인덱스를 리턴 }

쾌속정렬 메인함수 코드 9-7: 쾌속 정렬의 메인함수    void QuickSort(int A[ ], int First, int Last)    { if (First < Last)    {    int PivotIndex = Partition(A, First, Last);         QuickSort(A, First, PivotIndex-1);         QuickSort(A, PivotIndex+1, Last);      }    }

쾌속정렬 효율 정렬된 데이터에 최악의 효율 단계의 수에 따라 결정 단계의 수는 파티션 결과 좌우 정확히 양분되면 lgN 균형(Balancing)이 좋을 때 효율은 O(NlgN0 정렬된 데이터에 최악의 효율 파티션 결과 하나씩만 나가 떨어진 단계의 수는 거의 N

쾌속정렬의 균형 파티션 방법 피벗의 선택 (“세개 중 메디안” 파티션) 시스템 정렬 파티션의 최종단계 더 나은 균형을 위하여 같은 키에서도 스와핑 피벗의 선택 (“세개 중 메디안” 파티션) 처음 세 개, 마지막 세 개, 처음, 마지막, 중간 것 랜덤 함수에 의한 추출 어느 경우든 선택을 위한 시간이 소요됨. 시스템 정렬 샘플정렬 램덤하게 여러 샘플 추출, 정렬, 그 중 중간값을 피벗으로 벤틀리 매클로이 방식 한번에 3개의 샘플을 사용하여 메디안을 구함 3번 반복하여 3개의 메디안을 구한 뒤, 그 중의 메디안 값을 피벗으로 파티션의 최종단계 예를 들어 데이터 10개 이하 직접 삽입정렬에 의해 정렬 재귀호출에 따른 활성화 레코드 생성,복원에 따르는 시간 배제

합병정렬, 쾌속정렬 효율비교 합병정렬은 매 단계마다 완벽한 균형 합병정렬은 최악의 경우에도 O(NlgN)을 보장 쾌속정렬은 임시저장공간이 불필요한 제자리 연산(In-Place Computation) 합병정렬은 임시저장공간에 옮겨 가고 옮겨오는 시간이 필요 평균적으로는 쾌속정렬이 빠름

정렬방식 비교 합병정렬 쾌속정렬 삽입, 쾌속, 합병 N=103 N=106 N=109 PC 순간적 1초 18분 수퍼 컴   N=103 N=106 N=109 PC 순간적 1초 18분 수퍼 컴 N=103 N=106 N=109 PC 순간적 0.3초 6분 수퍼 컴   삽입 정렬 쾌속 정렬 합병 정렬 최악의 효율 N2 NlgN 최선의 효율 N 평균적 효율 이미 정렬된 데이터 반대로 정렬된 데이터 공간 2N 안정정렬 Yes No YES

외부정렬 기본적으로 합병정렬 1단계: 2단계: (3개씩 합병) 3단계: (3개씩 합병) 입력 파일: D A T A S T R U C T U R E A N D A L G O R I T H M 메인 메모리 용량이 세개 단위로 읽어 들여 정렬 가능하다고 가정 1단계: 파일 1: ADT * RTU * GOR * 파일 2: AST * AEN * HIT * 파일 3: CRU * ADL * M * 2단계: (3개씩 합병) 파일 4: AACDRSTTU * 파일 5: AADELNRTU * 파일 6: GHIMORT * 3단계: (3개씩 합병) 파일 1: AAAACDDEGHILMNORRSTTTTUU *

외부정렬 1단계: 2단계: (2개씩 합병) 3단계: (2개씩 합병) 4단계:(2개씩 합병) 5단계(2개씩 합병) 파일 1: ADT * RTU * GOR * 파일 2: AST * AEN * HIT * 파일 3: CRU * ADL * M * 2단계: (2개씩 합병) 파일 4: AADSTT * AADELN * M 파일 5: CRRTUU * GHIORT * 3단계: (2개씩 합병) 파일 1: AACDRRSTTTUU * M 파일 2: AADEGHILNORT * 4단계:(2개씩 합병) 파일 3: AAAACDDEGHILNORRSTTTTUU * 파일 4: M 5단계(2개씩 합병) 파일 1: AAAACDDEGHILMNORRSTTTTUU *

외부정렬 합병 효율 p개 단위의 합병 모든 블록이 합병에 참가하기만 하면 합병의 순서는 관계없음 CPU 연산시간 << 입출력 시간 외부정렬의 효율은 입출력시간에 좌우됨 몇 단계에 걸쳐 파일 출력이 일어나는가가 관건 1 단계 실행결과 정렬된 블록의 개수는 N/M 개 p개 단위의 합병 합병 한번에 블록의 개수는 1/p 씩 줄어듬 따라서 정렬의 효율은 대략 logp(N/M)

최선의 정렬효율 버블정렬의 결정트리 3개의 키이므로 크기 순서의 조합은 3! = 6 불필요한 비교를 감안하면 일반적으로 리프 노드의 수는 N! 개 이상 트리의 높이는 최소한 log2(N!) 보다 크고 최소 비교의 회수는 log2(N!). 스털링(Stirling)의 공식: log2(N!) ≥ log2(N/e)N = Nlog2N - Nlog2e. 따라서 정렬에서 가능한 최소 비교회수는 Nlog2N

버켓정렬 버켓정렬

버켓정렬 방법 효율 단점 키 자체를 배열 인덱스로 하여 별도 배열로 옮김 O(N). 키 비교에 의한 정렬이 아니므로 O(NlgN)을 능가할 수 있음 단점 버켓 배열의 인덱스보다 큰 키가 들어올 수 없음 버켓의 크기를 최대 인덱스 크기로 설정. 메모리 공간낭비 가능성 이를 개선한 것이 셈 정렬

셈 정렬 분포세기(Distribution Counting) 또는 셈 정렬(Count Sorting) 효율 중복 키 허용 키 빈도를 Count[ ] 배열에 넣음. Count[1]= 4, Count[2] = 2, Count[3] = 1 누계를 구하면 Count[1] = 4, Count[2] = 4 + 2 = 6, Count[3] = 6 + 1 = 7 오른쪽에서 왼쪽으로 스캔 해 가면서 버켓에 삽입 삽입 위치는 현재의 카운트 값. 삽입 직후에는 카운트 값을 하나씩 줄임 효율 O(N)로서 안정정렬

기수정렬 기수 = 키의 구성요소. 분해된 문자열, 분해된 문자.

기수정렬 기수정렬 기수 Radix = 뿌리 문자열 키의 뿌리는 문자. 문자의 뿌리는 비트 문자열 단위로 비교하는 대신 문자열을 잘라서 문자 단위로 비교 기수 8비트 ASCII 코드라면 256가지 레이딕스 16비트 유니코드(Unicode)라면 65,536 가지의 레이딕스 숫자를 문자열로 간주하면 숫자 키에 대해서도 기수 정렬을 가할 수 있음.

LSD 기수정렬 LSD 문자열 오른쪽(Least Significant Digit )에서 왼쪽으로 제대로 동작하는 이유는 안정성 때문. 왼쪽 키이가 같다면 오른쪽 키이는 이전에 정렬된 순서를 유지함 문자 단위의 정렬은 셈 정렬을 사용 문자열 길이 W일 때, 효율은 O(WN). a d 1 c b 2 f e 3 4 5 6 7   ⇧ c a b 1 d 2 3 4 e 5 f 6 7   ⇧ c a b 1 d 2 3 e 4 5 6 f 7   ⇧ a c e 1 d 2 b 3 4 5 6 7 f   [표 9-22)] D [표 9-19)] A [표 9-20)] B [표 9-21)] C

LSD 기수정렬 단점 패딩 최종 단계의 정렬이 이루어지기 전까지는 조금이라도 정렬된 흔적이 없음 가변 길이 키에 적용하기 어려움. cold 와 old 라는 키에 이 방식을 가하면 뒤에서부터 올라오므로 마지막 첫 자리에서 cold의 c와 비교되어야 하는 것이 old에는 없으므로 아무 것도 없음을 표시하는 널 문자(Null Character)와 비교. ASCII 코드 표에 의하면 c는 십진수 99, 널 문자는 십진수 0이므로 old, cold 순의 오름차순이 된다. 이는 잘못된 정렬 마지막 부근의 자릿수 정렬에 많은 시간을 허비. 만약 키가 Kim Pak Cho Rho 등이라면 사실은 첫 자리만 보고도 정렬이 가능한 것이다. 패딩 cold, old, at를 비교하자면 cold, old0, at00 등으로 마지막에 0을 보충 0은 아스키 값 십진수 47로서 문자보다는 그 값이 작음 숫자를 문자열로 취급할 경우에는 거꾸로 처음에 0을 넣어서 비교 1611, 315, 17을 비교하자면 1611, 0315, 0017로 비교 패딩은 번거로운 작업으로서 키의 최대 길이를 찾아내는 시간, 패딩 하는 시간을 요한다.

MSD 기수정렬 MSD 왼쪽 (MSD: Most Significant Digit) 에서 오른쪽으로 진행 셈 정렬(Distribution Counting)을 사용. O(WN) = O(N) 이전의 모든 문자가 일치하는 것들만 다음 문자를 비교 앞부분이 유일(Uniqueness) 해지면 더 이상 비교 대상에서 제외 a d 1 c b 2 f e 3 4 5 6 7   ⇧ a d 1 c e 2 b 3 4 5 6 7 f   ⇧ a c e 1 d 2 b 3 4 5 6 7 f   ⇧ a c e 1 d 2 b 3 4 5 6 7 f   [표 9-26)] G [표 9-23)] D [표 9-24)] E [표 9-25)] E

기수교환 정렬 기수교환 정렬 문자 단위의 정렬에 셈 정렬 대신 쾌속정렬 사용 별도 메모리 대신 스와핑 사용 3-way 파티션 피벗 b와 일치하지 않는 키(add, ace 그룹, dad, fee, cab 그룹)는 다시 첫 문자를 기분으로 재귀적으로 정렬해야 함. 피벗 b와 일치하는 키(bed, bad, bee)는 두번째 문자를 대상으로 정렬을 진행 a d 1 c b 2 f e 3 4 5 6 7   ⇧ a d 1 c e 2 b 3 4 5 6 f 7   ⇧ [표 9-27)] H [표 9-28)] I

비트단위의 기수교환정렬 파티션 파티션 결과 0인 그룹과 1인 그룹으로 양분 첫문자에 재귀적으로 파티션할 필요가 없음 비트단위의 쾌속정렬 비트 열이 유일(Uniqueness)해지면 더 이상 비교대상에서 제외시킴

비트 단위의 기수교환 정렬 유일한 비트열 통계적 분석 효율 파티션이 가해질 때마다 N개의 비트 값이 비교 데이터 N 개라면 대략적으로 log2N 비트 만에 모든 비트 열이 유일해 짐. 기수교환 정렬의 효율은 O(Nlog2N) 통계적 분석 통계적으로 볼 때, 어떤 자리수가 0일 확률과 1일 확률이 1/2로서 동일 비트 단위의 파티션을 가하면 데이터의 반이 0 그룹, 나머지 반이 1 그룹 균형적 파티션이므로 단계의 수는 쾌속 정렬에서 지속적으로 균형적인 파티션이 일어날 때의 단계 수인 log2N과 동일 균형이 일어날 확률이 높음으로 인해 쾌속 정렬보다 O(Nlog2N)에 근접 효율 소요되는 시간 면에서 비트 단위의 기수교환 정렬은 쾌속 정렬과 큰 차이 기수교환 정렬에서 O(Nlog2N)이라고 할 때에는 비트 단위의 비교회수 쾌속 정렬에서 O(Nlog2N)라고 할 때에는 문자열 단위의 비교회수