선택정렬
- 가장 작은 데이터를 선택해 맨 앞에 있는 데이터와 바꾼다.
- 한번씩 순회를 하고 가장 큰 수를 찾은다음 바꿈
- 시간 복잡도 : O(N*2)
- 공간 복잡도 : O(N)
int[] arr = {7, 5, 2, 4, 6, 1, 3, 9, 8};
for (int i = 0; i < arr.length; i++) {
int min = i;
for (int j = i+1; j < arr.length; j++) {
if (arr[min] > arr[j]) {
min = j;
}
}
int temp = arr[i];
arr[i] = arr[min];
arr[min] = temp;
}
삽입정렬
- 처리되지 않은 데이터를 하나씩 골라 적절한 위치에 삽입한다.
- 현재위치에서 아래쪽을 순회하며 크기가 작을수록 계속 swap을 해주는 정렬방식
- 시간 복잡도 : O(N*2)
- 공간 복잡도 : O(N)
- 하지만 거의 정렬되어있는 상태라면 매우빠르게 동작 : O(N)
int[] arr = {7, 5, 2, 4, 6, 1, 3, 9, 8};
for (int i = 1; i < arr.length; i++) {
for (int j = i; j > 0; j--) {
if (arr[j] < arr[j - 1]) {
int temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
} else {
break;
}
}
}
버블정렬
- 두개씩 짝을 지어서 정렬을 하나씩 실행함
- 시간 복잡도 : O(N*2)
- 공간 복잡도 : O(N)
int[] arr = {7, 5, 2, 4, 6, 1, 3, 9, 8};
for (int i = 1; i < arr.length; i++) {
for (int j = 0; j < arr.length-1; j++) {
if (arr[i] < arr[j]) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
퀵정렬
- 기준 데이터를 설정하고 기준보다 큰 데이터와 작은 데이터의 위치를 바꾸는 방법
- 가장 많이 사용되는 정렬 알고리즘
- 가장 기본적인 퀵 정렬은 첫 번째 데이터를 기준 데이터로 설정
- 시간 복잡도 : O(NlogN)
- 공간 복잡도 : O(N)
- 하지만 최악의 경우 O(N^2)
array = [5, 7, 9, 0, 3, 1, 6, 2, 4, 8]
def quick_sort(array):
# 리스트가 하나 이하의 원소만을 담고 있다면 종료
if len(array) <= 1:
return array
pivot = array[0] # 피벗은 첫 번째 원소
tail = array[1:] # 피벗을 제외한 리스트
left_side = [x for x in tail if x <= pivot] # 분할된 왼쪽 부분
right_side = [x for x in tail if x > pivot] # 분할된 오른쪽 부분
# 분할 이후 왼쪽 부분과 오른쪽 부분에서 각각 정렬을 수행하고, 전체 리스트를 반환
return quick_sort(left_side) + [pivot] + quick_sort(right_side)
print(quick_sort(array))
병합정렬
- 정렬할 리스트를 반으로 쪼개나가며 좌측과 우측 리스트를 계속해서 분할해 나간 후 각 리스트내에서 정렬 후 병합한다
- 시간복잡도 O(nlogn)을 보장
계수정렬
- 특정 조건이 부합할 때만 사용할 수 있지만 매우 빠르게 동작하는 알고리즘
- 데이터의 크기 범위가 제한되어 정수 형태로 표현할 수 있을 때 사용 가능
- 데이터의 개수가 N, 데이터(양수) 중 최댓값이 K일 때 최악의 경우에도 O(N+K)
- 공간복잡도 : O(N+K)
- 동일한 값을 가지는 데이터가 여러 개 등장할 때 효과적으로 사용가능
# 모든 원소의 값이 0보다 크거나 같다고 가정
array = [7, 5, 9, 0, 3, 1, 6, 2, 9, 1, 4, 8, 0, 5, 2]
# 모든 범위를 포함하는 리스트 선언 (모든 값은 0으로 초기화)
count = [0] * (max(array) + 1)
for i in range(len(array)):
count[array[i]] += 1 # 각 데이터에 해당하는 인덱스의 값 증가
for i in range(len(count)): # 리스트에 기록된 정렬 정보 확인
for j in range(count[i]):
print(i, end=' ') # 띄어쓰기를 구분으로 등장한 횟수만큼 인덱스 출력
- 0,999999만 존재하는 경우를 생각해보면 1,000,000개의 공간을 만들어야하기 때문에 매우 비효율적
퀵정렬
- 가장 많이 쓰는 정렬알고리즘
- pivot을 선정하여 pivot을 기준으로 좌측과 우측으로 pivot보다 작은값은 왼쪽 pivot보다 큰값은 오른쪽으로 재배치를 하고 계속하여 분할하여 정렬하는 알고리즘
- 일반적으로 O(nlogn), 최악O(N^2)
'Algorithm > concept' 카테고리의 다른 글
Coding Test(Topological Sort) (0) | 2022.09.17 |
---|---|
Coding Test(최단 경로 - Dijkstra, Bellman-Ford, Floyd-Warsahall) (0) | 2022.08.27 |
Coding Test(Prim Algorithm) (0) | 2022.08.23 |
Coding Test(Kruskal Algorithm) (0) | 2022.08.23 |
Coding Test(Two Pointer) (0) | 2022.06.06 |