


3
9 1 2 3 4 5 6 7 8 9
9 9 8 7 6 5 4 3 2 1
9 9 6 3 1 2 4 5 7 8
: 인접한 두 숫자를 비교하여 두 수의 정렬순서가 맞지 않는 경우에 교환
void bubbleSort(int a[], int n)
{
int countCmpOps = 0;
int countSwaps = 0;
for (int i=0; i<n-1; i++) {
for (int j=0; j<n-i-1; j++) {
countCmpOps++;
if (a[j+1] < a[j]) {
countSwaps++;
swap(a[j+1], a[j]);
}
}
}
printf("%d %d ", countCmpOps, countSwaps);
}
36 0
36 36
36 15
void bubbleSortImproved1(int a[], int n)
{
int countCmpOps = 0;
int countSwaps = 0;
bool swapped;
for (int i=0; i<n-1; i++) {
swapped = false;
for (int j=0; j<n-i-1; j++) {
countCmpOps++;
if (a[j+1] < a[j]) {
countSwaps++;
swap(a[j+1], a[j]);
swapped = true;
}
}
if (swapped == false) {
break;
}
}
printf("%d %d ", countCmpOps, countSwaps);
}
8 0
36 36
26 15
void bubbleSortImproved2(int a[], int n)
{
int countCmpOps = 0;
int countSwaps = 0;
int lastSwappedPos = n-1;
int swappedPos;
while(lastSwappedPos) {
swappedPos = 0;
for (int j=0; j<lastSwappedPos; j++) {
countCmpOps++;
if (a[j+1] < a[j]) {
countSwaps++;
swap(a[j+1], a[j]);
swappedPos = j;
}
}
lastSwappedPos = swappedPos;
}
printf("%d %d ", countCmpOps, countSwaps);
}
8 0
36 36
20 15
C++ 컴파일러는 함수 선언(prototype)이 함수 호출보다 먼저 나와야 하는 C 언어의 규칙을 따르지 않아도 됩니다. 이러한 특징을 "전방 선언" 또는 "함수 프로토타입"이라고 합니다. 함수의 정의(implementation)는 함수 호출보다 아래에 있어도 상관없습니다.
따라서 코드에서
swap함수의 선언이 호출보다 아래에 있어도 문제없이 동작합니다. 컴파일러는 함수 호출 시 해당 함수의 프로토타입(선언)을 찾아서 컴파일합니다. 때문에 함수의 정의가 프로토타입보다 나중에 나와도 컴파일러는 정상적으로 동작합니다.이러한 특징은 코드의 가독성을 높일 수 있으며, 관련 함수를 한데 모아 두지 않아도 되므로 큰 프로젝트에서 유용합니다. 함수의 구현을 코드의 다른 부분과 더 관련성 있게 배치할 수 있습니다.
void combSort(int a[], int n) {
int countCmpOps = 0;
int countSwaps = 0;
int gap = n;
float shrink = 1.3;
bool sorted = false;
while (!sorted) {
gap = gap / shrink;
if (gap <= 1) {
gap = 1;
sorted = true;
}
int i = 0;
while (i + gap < n) {
countCmpOps++;
if (a[i] > a[i + gap]) {
countSwaps++;
swap(a + i, a + i + gap);
}
i++;
}
}
printf("%d %d\n", countCmpOps, countSwaps);
}
29 0
29 6
37 7
: 오른쪽 데이터에서 가장 작은 값을 오른쪽 데이터의 첫번째 값과 교환
Not Stable

In-place
void selectionSort(int a[], int n)
{
int countCmpOps = 0;
int countSwaps = 0;
int minIndex = 0;
for (int i=0; i<n-1; i++) {
minIndex = i;
for (int j=i+1; j<n; j++) {
countCmpOps++;
if (a[minIndex] > a[j]) {
minIndex = j;
}
}
if (minIndex != i) {
swap(a + i, a + minIndex);
countSwaps++;
}
}
printf("%d %d\n", countCmpOps, countSwaps);
}
: 오른쪽 데이터를 순서대로 왼쪽의 정렬된 데이터의 올바른 위치에 삽입
void insertionSort(int a[], int n)
{
int countCmpOps = 1;
int countSwaps = 0;
for (int i=0; i<n-1; i++) {
for (int j=i; j>=0 && countCmpOps++ && a[j] > a[j+1]; j--) {
countSwaps++;
swap(a + j, a + j + 1);
}
}
printf("%d %d\n", countCmpOps-1, countSwaps);
}

: 같은 gap을 가지는 모든 gap sequence에 insertion sort를 수행
void ShellSort(int a[], int n)
{
int countCmpOps = 1;
int countSwaps = 0;
int shrinkRatio = 2;
int gap = n / shrinkRatio;
int tmp, j, i;
while (gap > 0) {
for (i=0; i<n; i++) {
tmp = a[i];
for (j=i; j-gap>=0 && countCmpOps++ && tmp < a[j-gap]; j-=gap) {
countSwaps++;
a[j] = a[j - gap];
}
a[j] = tmp;
}
gap /= shrinkRatio;
}
printf("%d %d\n", countCmpOps-1, countSwaps);
}
20 0
22 8
23 7