알고리즘은 입력, 출력, 유한성, 명시성 및 효율성을 충족해야 합니다.
병합, 정렬
분할 정복 방법은 큰 문제를 두 개의 작은 문제로 나누어 별도로 계산한 다음 결합하는 방법을 사용합니다. 즉, 무조건 이등분하고 나중에 정렬하는 알고리즘입니다. $O(N*log_{2}{N})$항상 보장
그러나 기존 데이터를 보관하려면 추가 어레이가 필요하므로 메모리 사용이 비효율적일 수 있습니다.
백준 2750
package Y2023.March.week2;
import java.util.Scanner;
public class q2750 {
static int() sorted;
static void merge(int() sort, int start, int mid, int end){
int() arr = sort.clone();
int i = start;
int j = mid+1;
int k = start;
while(k<=end){
if(i>mid){
sorted(k) = arr(j++);
}else if(j>end){
sorted(k) = arr(i++);
}else if(arr(i)<arr(j)){
sorted(k) = arr(i++);
}else{
sorted(k) = arr(j++);
}
k++;
}
}
static void mergeSort(int() arr, int start, int end){
if(start < end){
int mid = (start+end)/2;
mergeSort(arr, start, mid);
mergeSort(arr, mid+1, end);
merge(arr, start, mid, end);
}
}
public static void main(String() args) {
Scanner sc = new Scanner(System.in);
StringBuilder sb = new StringBuilder();
int len = sc.nextInt();
sorted = new int(len);
for(int i=0; i<len; i++){
sorted(i) = sc.nextInt();
}
mergeSort(sorted, 0, len-1);
for(int i=0; i<len; i++){
sb.append(sorted(i)).append("\n");
}
System.out.println(sb);
}
힙 정렬
힙 트리 구조를 사용하는 정렬 방법입니다. 병합 정렬과 퀵 정렬처럼 $O(N*log_{2}{N})$의 시간복잡도를 갖는다
힙은 2023.03.02 – (D • A/DataStructure) – (데이터 구조) 완전 이진 트리 – 힙 입니다. 여기서
1. 모든 요소(N)를 기반으로 최대 힙을 생성합니다(최대 힙 생성 알고리즘).
- 자식 노드가 없는 노드를 제외하고 부모 노드는 끝에서 자식 노드와 비교됩니다.
- 이 시점에서 부모 노드는 인덱스(자식)/2에 있으므로 모든 부모 노드는 힙 크기 인덱스의 절반까지만 존재합니다. 따라서 요소의 길이/2 인덱스에서 앞으로 이동하면 부모 노드만 선택됩니다.
- 자식 노드가 부모 노드보다 크면 서로 교환합니다.
- 한 칸씩 위로 올라갑니다.
2. 최대 힙의 루트, 즉 최대값을 마지막 요소로 바꿉니다.
3. 마지막 요소, 즉 최대값이 아닌 요소로 최대 힙을 생성합니다(최대 힙 삭제 알고리즘).
- 루트 노드부터 부모 노드를 자식 노드와 비교하여 더 큰 값으로 교환합니다.
- 교환되는 시점에서 다시 자식노드와 비교하여 더 큰 값으로 교환한다.
- 자식 노드 아래에 더 큰 값이 없을 때까지 이 프로세스를 반복합니다.
4. 2단계와 3단계를 반복하여 정렬합니다.
Heapsort는 Heapify 알고리즘을 사용합니다. 힙 구조를 한 번 생성하려면 높이만 재실행하면 되기 때문에 시간 복잡도는 $O(logN)$입니다. Heapify를 한 번 반복할 때 각 노드에 N을 곱해야 하므로 $N*logN$ 번 실행하면 정렬됩니다.
병합 정렬과 달리 힙 정렬은 추가 메모리가 필요하지 않다는 점에서 효율적입니다. 하지만 속도만 비교한다면 퀵소트가 더 빠릅니다.
정렬 카운팅
크기에 따라 숫자를 세는 알고리즘입니다. 따라서 범위 조건이 있는 경우에만 매우 빠릅니다. $O(N)$의 시간복잡도를 갖는다
1. 길이가 최대 요소의 값인 배열을 만들고 숫자에 해당하는 인덱스에 하나씩 1을 더합니다.
2. 처리가 완료되면 인덱스의 값, 즉 반복 횟수만큼 반환한다.
매우 빠르지만 값 자체의 범위를 메모리에서 표현할 수 있어야 합니다.
백준 15688
package Y2023.March.week2;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Scanner;
public class q15688 {
public static void main(String() args) throws IOException {
//Scanner sc = new Scanner(System.in);
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
int len = Integer.parseInt(br.readLine());
int()() arr = new int(2)(1000001);
Arrays.fill(arr(0),0);
Arrays.fill(arr(1),0);
int in;
for (int i = 0; i < len; i++) {
in = Integer.parseInt(br.readLine());
if(in<0)
arr(0)(-in)++;
else
arr(1)(in)++;
}
for (int i = 1000000; i >0 ; i--) {
if(arr(0)(i)!=0)
for(int j=0; j<arr(0)(i); j++){
sb.append(-i).append("\n");
}
}
for (int i = 0; i < 1000001; i++) {
if(arr(1)(i)!=0)
for(int j=0; j<arr(1)(i); j++){
sb.append(i).append("\n");
}
}
System.out.println(sb);
}
}

![[알고리즘이론] 파이썬 자료구조 [알고리즘이론] 파이썬 자료구조](https://file.foodle.kr/wp-content/plugins/contextual-related-posts/default.png)