거품정렬, 선택정렬, 삽입정렬에 대해 알아보겠다
세가지의 정렬을 알아보기전에 In-place정렬이 무엇인지 알아보자
쉽게 말하자면 외부 메모리를 거의 쓰지않고 주어진 배열 내부의 swap이나 대입으로 작업을 수행하는 것
제자리 알고리즘 이라고도 한다
- 버블정렬 : swap
- 선택정렬 : swap
- 삽입정렬 : 대입
서로 인접한 두 원소를 비교하여 정렬하는 알고리즘이다
- 정렬이 다 되고 출력해보면 오름차순으로 정렬이 된다
- 버블정렬의 시간복잡도 O(N²)
#include <iostream>
#define SIZE 5
using namespace std;
int main()
{
#pragma region 거품 정렬
// 오름차순 정렬
int array[SIZE] = { 5, 8, 2, 1, 4 };
// 회차
for (int i = 0; i < SIZE - 1; i++)
{
// 안쪽 정렬
for (int j = 0; j < (SIZE - i) - 1; j++)
{
// 왼쪽이 더 크다면 swap
if (array[j] > array[j + 1])
{
swap(array[j], array[j + 1]);
}
}
}
for (const int& element : array)
{
cout << element << " ";
}
#pragma endregion
return 0;
}

주어진 리스트 중에 최소값을 찾아서 맨 앞에 위치한 결과를 교체하는 방식으로 정렬하는 알고리즘이다
- 선택정렬의 시간복잡도 O(N²)
#include <iostream>
#define SIZE 5
using namespace std;
int main()
{
#pragma region 선택 정렬
int min = 0;
int minIndex = 0;
int array[SIZE] = { 6, 2, 8, 1, 0 };
// 마지막 값은 알아서 정렬되기 때문에 SIZE - 1
// SIZE로 해도 무관하긴 함
// 0 1 2 3
for (int i = 0; i < SIZE - 1; i++)
{
// 1. 최소값 찾기
min = array[i];
minIndex = i;
for (int j = i + 1; j < SIZE; j++)
{
// 최소값 교체
if (array[j] < min)
{
min = array[j];
minIndex = j;
}
}
// 실제 값 변경
swap(array[i], array[minIndex]);
}
for (const int& element : array)
{
cout << element << " ";
}
#pragma endregion
return 0;
}

데이터를 하나씩 확인하면서 이미 정렬된 부분과 비교하여 자신의 위치를 찾아 삽입하는 방식으로 정렬하는 알고리즘이다
- 삽입정렬의 시간복잡도 O(N²)
key값은 내가 삽입하고 싶은 값이다
-> 첫 번째 원소[0]는 이미 정렬된 상태로 간주되기 때문에 key값을 저장하는 반복은 [1]부터 SIZE까지
안쪽 for문의 조건식은 j값이 i - 1부터 시작해서 j--를 거쳐 j가 0과 같거나 작아지면 중지한다
그리고 array [j] 값이 key값보다 크다면 반복, array [j]값이 더 작아지면 중지
-> i의 앞쪽에 정렬된 값을 뒤에서 부터 차례로 확인하는 것
key값보다 array [j] 값보다 작다면, array[j+1]의 위치에 array[j]값을 대입
-> 기존의 key값은 변수에 저장되어 있기 때문에 덮어씌워져도 괜찮음 (나중에 key값을 다시 대입할 예정)
안쪽 for문이 종료되면 비교 위치에 key값을 다시 삽입한다
#include <iostream>
#define SIZE 5
using namespace std;
int main()
{
#pragma region 삽입 정렬
// 키값과 왼쪽에 값들을 비교한 뒤 그 자리에 키값을 대입
// 0번째 인덱스의 수는 그 자체로 정렬이 되어있으므로 [1]부터 시작
int array[SIZE] = { 6,12,4,1,7 };
int key = 0;
int j = 0;
// 1 2 3 4
for (int i = 1; i < SIZE; i++)
{
// 키값 저장
key = array[i];
for (j = i - 1; j >= 0 && array[j] > key; j--)
{
// key위치의 인덱스의 값을 j값으로 대입
array[j + 1] = array[j];
}
// 비교 위치에 key값 삽입 (j가 -가 되는걸 방지)
array[j + 1] = key;
}
for (const int& element : array)
{
cout << element << " ";
}
#pragma endregion
return 0;
}
for문에서도 사용하고, 밖에서도 사용하기 위해서다
-> 변수의 재사용성을 높임!


