180 likes | 344 Views
정렬 알고리즘. 박형준. 사용자 정의 타입 사용. 반드시 정의해야 될 것들 ! 디폴트 생성자 복사 생성자 operator= operator== 검색에서 많이 사용한다 . operator> 비교로 greater than 만 사용한다. 사용자 정의 타입 사용. 그렇다면 나머지 비교 연산자들은 어떻게 처리해야 할까 ? 1. a < b -> b > a 2. a >= b -> a > b || a == b 3. a <= b -> b > a || a == b 4. a != b -> !(a == b).
E N D
정렬 알고리즘 박형준
사용자 정의 타입 사용 • 반드시 정의해야 될 것들! • 디폴트 생성자 • 복사 생성자 • operator= • operator== • 검색에서 많이 사용한다. • operator> • 비교로 greater than만 사용한다.
사용자 정의 타입 사용 • 그렇다면 나머지 비교 연산자들은 어떻게 처리해야 할까? • 1. a < b -> b > a • 2. a >= b -> a > b || a == b • 3. a <= b -> b > a || a == b • 4. a != b -> !(a == b)
선택 정렬 • 1. 주어진 리스트 중 최소값을 찾는다. • 2. 그 값을 맨 앞에 위치한 값과 교체한다. • 3. 맨 처음 위치를 뺀 나머지 리스트를 같은 방법으로 교체한다. • 비교하는 것이 상수 시간에 이루어지는 가정 아래, n개의 주어진 리스트를 이와 같은 방법으로 정렬하는 데에는 Θ(n2) 만큼의 시간이 걸린다.
선택 정렬 의사코드 • For i = 0 to n: • a[i]부터 a[n-1]까지차례로 비교하여 가장 작은 값을 a[j]에 있다고 하자. • a[i]와 a[j]의 값을 서로 바꾼다.
선택 정렬 실제 코드 template < class T > void SelectionSort( T* pArray, intnArrayCount ) { intnMinIndex = 0; intnProgressCount = 0; while( nProgressCount != nArrayCount ) { nMinIndex = nProgressCount; for( int j = nMinIndex + 1; j < nArrayCount; ++j ) { if( pArray[nMinIndex] > pArray[j] ) nMinIndex = j; } // 구한최소값을설정한다. T temp = pArray[nMinIndex]; pArray[nMinIndex] = pArray[nProgressCount]; pArray[nProgressCount] = temp; // 진행바를늘인다. nProgressCount++; } }
선택정렬 코드 분석 • intnMinIndex = 0;intnProgressCount = 0;최소값을 가리키는 인덱스와 진행 카운터를 보관하는 변수를 선언해 놓고 있다. • While( nProgressCount < nArrayCount ) 진행바가 최대 배열 개수가 되지 않을 때까지 진행을 계속 하도록 한다.
선택정렬 코드 분석 • for( int j = nMinIndex + 1; j < nArrayCount; ++j ) { if( pArray[nMinIndex] > pArray[j] ) nMinIndex = j; } 선택된 위치 이후부터 배열의 끝까지 순회하며 최소값을 찾는다. 찾았으면 최소 인덱스를 갱신해준다.
선택정렬 코드 분석 • // 구한최소값을설정한다. T temp = pArray[nMinIndex]; pArray[nMinIndex] = Array[nProgressCount]; pArray[nProgressCount]= temp; // 진행바를늘인다. nProgressCount++; 이젠 구한 최소값을 현재 변경하고자 하는 위치와 Swap을 통해 바꾸는 것으로 끝이다.
삽입 정렬 • 자료 배열의 모든 요소를 앞에서부터 차례대로 이미 정렬된 배열 부분과 비교하여, 자신의 위치를 찾아 삽입함으로써 정렬을 완성한다. • 배열이 길어질수록 효율이 떨어지지만, 구현이 간단하다는 장점이 있다. • 선택정렬이나 거품정렬과 같은 O(n2)알고리즘에 비교하여 빠르며, 안정 정렬이고 in-place 알고리즘이다.
삽입 정렬 실제 코드 template < class T > void InsertSort( T* pArray, intnArrayCount ) { intnProgressCount = 1; while( nProgressCount < nArrayCount ) { intnMinIndex = nProgressCount; for( int j = nProgressCount-1; j >= 0; --j ) { if( pArray[j] > pArray[nMinIndex] ) { T temp = pArray[j]; pArray[j] = pArray[nMinIndex]; pArray[nMinIndex] = temp; --nMinIndex; } else break; } nProgressCount++; } }
삽입 정렬 코드 분석 • for( int j = nProgressCount-1; j >= 0; --j )정렬이 되지 않는 위치 – 1부터 0이 될때까지 루프를 순회한다.
삽입 정렬 코드 분석 • if( pArray[j] > pArray[nMinIndex] ) { if( pArray[j] > pArray[nMinIndex] ){ Swap( pArray[j], pArray[nMinIndex] ); --nMinIndex; } else break; 만약 이전 값이 현재 정렬될 위치의 값보다 크다면 swap을 통해 위치를 교환한다. 만약 그게 아니면 break문을 통해 더 이상 루프를 순회할 필요 없이 빠져 나온다.
거품 정렬 • 두 인접한 원소를 검사하여 정렬하는 방법이다. • 시간 복잡도가 O(n2)로 상당히 느리지만 코드가 단순하다. • 원소의 이동이 거품이 수면으로 올라오는 듯한 모습을 보이기 때문에 지어진 이름이다. • procedurebubbleSort( A : list of sortable items ) defined as:for eachiin 1 to length(A) do:for each j in length(A) downtoi + 1 do:ifA[ j ] < A[ j - 1 ] thenswap( A[ j ], A[ j - 1 ] )end if end for end forend procedure
거품 정렬 실제 코드 template < class T > void BubbleSort( T* pArray, intnArrayCount ) { intnProgressCount = 0; while( nProgressCount < nArrayCount ) { for( int j = 1; j < nArrayCount - nProgressCount; ++j ) { if( pArray[j] < pArray[j-1] ) { T temp = pArray[j]; pArray[j] = pArray[j-1]; pArray[j-1] = temp; } } nProgressCount++; } }
거품 정렬 코드 분석 • for( int j = 1; j < nArrayCount - nProgressCount; ++j )보는바와 같이 1번째 항목부터 시작해서 현재 진행된 번째의 값을 배열 개수에 빼준 그 값까지 루프를 순회한다.왜냐하면 거품정렬은 for문을 완료할 때마다 그 뒤의 값은 정렬이 되기 때문이다.즉, 정렬된 값을 다시 비교할 필요가 없기 때문이다.
거품 정렬 코드 분석 if( pArray[j] < pArray[j-1] ) { T temp = pArray[j]; pArray[j] = pArray[j-1]; pArray[j-1] = temp; }이전 값과 현재 위치한 값을 비교하여 만약 이전 값이 더 크다면 현재 값과 swap을 통해 자리를 교환하도록 하여 오름차순 정렬을 완성할 수 있는 것이다.