정렬 알고리즘은 목록의 요소들을 순서대로 넣는 알고리즘이다.
-위키백과
데이터를 정렬해야 하는 이유는 탐색을 위해서이다. 사람은 수십에서 수백 개의 데이터를 다루는 데 그치지만 컴퓨터가 다뤄야 할 데이터는 보통이 백만 개 단위이며 데이터베이스 같은 경우 이론상 무한 개의 데이터를 다룰 수 있어야 한다. 데이터가 정렬되어 있다면 효율적으로 정보를 탐색할 수 있다.
-나무위키
- 정렬 방법의 따라 시간복잡도가 다르다.
- 정렬 방법의 따라 공간복잡도가 다르다.
- Stable/unstable한 정렬의 필요성.
-임베디드 블로그
🎯 빅오는 무엇인가?
종류(작은 순):
array arr[] = {5, 1, 4, 2, 8}
❗ 노랑: 비교되는 node
1st pass:
{5 1 4 2 8} -> {1 5 4 2 8} //5 > 1, 교환.
{1 5 4 2 8} -> {1 4 5 2 8} //5 > 4, 교환.
{1 4 5 2 8} -> {1 4 2 5 8} //5 > 2, 교환.
{1 4 2 5 8} -> {1 4 2 5 8} //5 < 8 교환 하지 않음.arr[] == {1 4 2 5 8}
2nd pass:
{1 4 2 5 8} -> {1 4 2 5 8}
{1 4 2 5 8} -> {1 2 4 5 8} //4 > 2, 교환.
{1 2 4 5 8} -> {1 2 4 5 8}
{1 2 4 5 8} -> {1 2 4 5 8}arr[] == {1 2 4 5 8}
3rd pass:
{1 2 4 5 8} -> {1 2 4 5 8}
{1 2 4 5 8} -> {1 2 4 5 8}
{1 2 4 5 8} -> {1 2 4 5 8}
{1 2 4 5 8} -> {1 2 4 5 8}arr[] == {1 2 4 5 8}
🎯 정렬이 되어있지만 교환 없이 처음부터 끝까지 통과해야 정렬되었음을 알 수 있음.
👍 정렬 중 가장 심플하다.
👎 시간 복잡도가 아주 높아 대량의 데이터를 정렬하기 적합하지 않다.
💯평가 | |
---|---|
시간 복잡도 | O(n) |
공간 복잡도 | O(1) |
Stable vs Unstable | Stable |
array arr[] = {5, 1, 4, 2, 8}
❗ 노랑: 비교되는 node
1st pass (Key: 1):
{5 1 4 2 8} -> {1 5 4 2 8} //5 > 1, 5자리에 1 삽입.
arr[] == {1 5 4 2 8}
2nd pass (Key: 4):
{1 5 4 2 8} -> {1 4 5 2 8} //5 > 4, 교환.
{1 4 5 2 8} -> {1 4 5 2 8} //1 < 4, 5자리에 4 삽입.arr[] == {1 4 5 2 8}
3rd pass (Key: 2):
{1 4 5 2 8} -> {1 4 2 5 8} //5 > 2, 교환.
{1 4 2 5 8} -> {1 2 4 5 8} //4 > 2, 교환.
{1 2 4 5 8} -> {1 2 4 5 8} //1 < 2, 4자리에 2삽입....
arr[] == {1 2 4 5 8}
🎯 삽입될 위치를 찾고 기존 자리까지 존재하는 node들이 한칸씩 뒤로 이동됨.
👍 정렬 중 가장 직관적이다.
👎 시간 복잡도가 아주 높아 대량의 데이터를 정렬하기 적합하지 않다.
💯평가 | |
---|---|
시간 복잡도 | O(n) |
공간 복잡도 | O(1) |
Stable vs Unstable | Stable |
array arr[] = {5, 1, 4, 2, 8}
❗ 노랑: 정렬된 배열
1st pass:
{5 1 4 2 8} -> {1 5 4 2 8} //1, 5와 교환.
arr[] == {1 5 4 2 8}
2nd pass:
{1 5 4 2 8} -> {1 2 4 5 8} //2, 5와 교환.
...
arr[] == {1 2 4 5 8}
🎯 각 pass마다 가장 작은 값이 맨앞에 오게 되는 과정을 반복한다.
👍 직관적이고 심플하다.
👎 Unstable한 정렬이다.
💯평가 | |
---|---|
시간 복잡도 | O(n) |
공간 복잡도 | O(1) |
Stable vs Unstable | Unstable |
array arr[] = {5, 1, 4, 6, 2, 8}
❗ 노랑: pivot
❗ 분홍: low
❗ 주황: high1st pass (Pivot: 5):
{5 1 4 6 2 8}
1 < 5 ⭕
8 > 5 ⭕low, high 한칸씩 이동.
arr[] == {5 1 4 6 2 8}
2nd pass (Pivot: 5):
{5 1 4 6 2 8}
4 < 5 ⭕
2 > 5 ❌//high 정지.
{5 1 4 6 2 8}
6 < 5 ❌
2 > 5 ❌low와 high둘다 조건을 성사하지 못해 교환.
arr[] == {5 1 4 2 6 8}
3rd pass (Pivot: 5):
{5 1 4 2 6 8}
low와 high가 서로 지나침.
피봇과 high 교환.{2 1 4 5 6 8}
피봇 (5)는 이미 정렬된 상태.
피봇의 왼쪽과 오른쪽을 같은 작업을 반복한다. (분할 정복)
- {2 1 4} 5 {6 8}
정렬된 배열들은 결합한다.
...
arr[] == {1 2 4 5 6 8}
🎯 분할 (Divide)-> 정복 (Conquer)-> 결합 (Combine) 과정.
👍 정렬 중 속도가 빠른 편이다.
👍 추가 메모리 공간이 필요없다.
👎 이미 정렬된 리스트에 대해서는 수행시간이 더 걸린다.
💯평가 | |
---|---|
시간 복잡도 | O(n n) |
공간 복잡도 | O( n) |
Stable vs Unstable | Unstable |
array arr[] = {5 1 4 6 2 8}
❗ 노랑: left
❗ 분홍: right...(분할)
{5} {1} {4} {6} {2} {8}
...(합병)
1st pass:
{1 4 5} {2 6 8}
sorted arr[] = {1}
2nd pass:
{1 4 5} {2 6 8}
sorted arr[] = {1 2}
3rd pass:
{1 4 5} {2 6 8}
sorted arr[] = {1 2 4}
4th pass:
{1 4 5} {2 6 8}
sorted arr[] = {1 2 4 5}
5th pass:
{1 4 5} {2 6 8} //둘중 하나가 먼저 끝나면 나머지 값들을 전부 복사한다.
sorted arr[] = {1 2 4 5 6 8}
🎯 분할 (Divide)-> 정복 (Conquer)-> 결합 (Combine) 과정.
👍 정렬 중 속도가 빠르고, 효율적인 편이다.
👎 초보자가 구현하기에 복잡하다.
💯평가 | |
---|---|
시간 복잡도 | O(n n) |
공간 복잡도 | O(n) |
Stable vs Unstable | Stable |