소개
병합 정렬 (Merge Sort) 은 배열 정렬을 위해 분할 정복 (Divide and Conquer) 기법을 사용하는 효율적이고 안정적인 정렬 알고리즘입니다. 이 Lab 에서는 재귀적 접근 방식을 사용하여 Java 에서 병합 정렬을 구현하는 방법을 배우게 됩니다.
병합 정렬 (Merge Sort) 은 배열 정렬을 위해 분할 정복 (Divide and Conquer) 기법을 사용하는 효율적이고 안정적인 정렬 알고리즘입니다. 이 Lab 에서는 재귀적 접근 방식을 사용하여 Java 에서 병합 정렬을 구현하는 방법을 배우게 됩니다.
int arrToSort[], startIdx, endIdx 세 개의 정수 매개변수를 갖는 mergeSort()라는 public static 메서드를 생성합니다. 배열 길이가 2 미만인지 확인한 다음 반환해야 합니다. 그렇지 않으면 배열의 중간 인덱스를 계산하고 배열을 왼쪽 및 오른쪽 절반으로 분할합니다. 왼쪽 및 오른쪽 절반도 재귀적으로 분할해야 합니다. 분할 후에는 정렬된 배열을 형성하기 위해 병합해야 합니다.
public static void mergeSort(int[] arrToSort, int startIdx, int endIdx) {
if (startIdx >= endIdx) {
return;
}
int midIdx = startIdx + (endIdx - startIdx) / 2;
mergeSort(arrToSort, startIdx, midIdx);
mergeSort(arrToSort, midIdx + 1, endIdx);
merge(arrToSort, startIdx, midIdx, endIdx);
}
int arrToSort[], startIdx, midIdx, 및 endIdx의 네 가지 매개변수를 갖는 merge()라는 다른 public static 메서드를 생성합니다. 왼쪽 및 오른쪽 배열을 초기화해야 합니다. 그런 다음 각 배열의 요소를 비교하고 단일 배열로 병합하여 두 배열을 병합해야 합니다.
public static void merge(int[] arrToSort, int startIdx, int midIdx, int endIdx) {
int[] leftArr = new int[midIdx - startIdx + 1];
int[] rightArr = new int[endIdx - midIdx];
for (int i = 0; i < leftArr.length; i++) {
leftArr[i] = arrToSort[startIdx + i];
}
for (int i = 0; i < rightArr.length; i++) {
rightArr[i] = arrToSort[midIdx + i + 1];
}
int leftArrIdx = 0, rightArrIdx = 0, sortedArrIdx = startIdx;
while ((leftArrIdx < leftArr.length) && (rightArrIdx < rightArr.length)) {
if (leftArr[leftArrIdx] < rightArr[rightArrIdx]) {
arrToSort[sortedArrIdx] = leftArr[leftArrIdx];
leftArrIdx += 1;
} else {
arrToSort[sortedArrIdx] = rightArr[rightArrIdx];
rightArrIdx += 1;
}
sortedArrIdx += 1;
}
while (leftArrIdx < leftArr.length) {
arrToSort[sortedArrIdx] = leftArr[leftArrIdx];
leftArrIdx += 1;
sortedArrIdx += 1;
}
while (rightArrIdx < rightArr.length) {
arrToSort[sortedArrIdx] = rightArr[rightArrIdx];
rightArrIdx += 1;
sortedArrIdx += 1;
}
}
입력 배열을 정렬하는 코드를 작성하여 mergeSort() 메서드를 테스트해 보겠습니다. main 메서드를 생성합니다. 그런 다음, 정렬되지 않은 몇 개의 값을 가진 정수 배열을 선언합니다. mergeSort() 메서드를 호출하고 정렬되지 않은 배열을 전달합니다. 마지막으로, 정렬된 배열을 콘솔에 출력합니다. 이 단계의 코드 블록은 다음과 같습니다.
public static void main(String[] args) {
int[] arrToSort = { 4, 2, 8, 0, 1, 6 };
mergeSort(arrToSort, 0, arrToSort.length - 1);
System.out.println(Arrays.toString(arrToSort));
}
프로그램을 실행한 후 출력은 다음과 같아야 합니다: [0, 1, 2, 4, 6, 8].
빈 배열에 대한 다른 테스트를 생성합니다. 빈 정수 배열을 선언합니다. mergeSort() 메서드를 호출하고 빈 배열을 전달합니다. 마지막으로, 정렬된 배열을 콘솔에 출력합니다. 이 단계의 코드 블록은 다음과 같습니다.
int[] emptyArr = {};
mergeSort(emptyArr, 0, emptyArr.length - 1);
System.out.println(Arrays.toString(emptyArr));
출력은 입력과 동일해야 합니다.
단일 요소 배열로 테스트를 하나 더 생성합니다. 단일 요소 정수 배열을 선언합니다. mergeSort() 메서드를 호출하고 단일 요소 배열을 전달합니다. 마지막으로, 정렬된 배열을 콘솔에 출력합니다. 이 단계의 코드 블록은 다음과 같습니다.
int[] singleElementArr = {7};
mergeSort(singleElementArr, 0, singleElementArr.length - 1);
System.out.println(Arrays.toString(singleElementArr));
출력은 입력과 동일해야 합니다.
음수 정수로 구성된 배열에 대한 다른 테스트를 생성합니다. 일부 음수 정수를 포함하는 정수 배열을 선언합니다. mergeSort() 메서드를 호출하고 배열을 인수로 전달합니다. 마지막으로, 정렬된 배열을 콘솔에 출력합니다. 이 단계의 코드 블록은 다음과 같습니다.
int[] arrWithNegatives = {-7, 2, -9, 0, -1, 6, 8};
mergeSort(arrWithNegatives, 0, arrWithNegatives.length - 1);
System.out.println(Arrays.toString(arrWithNegatives));
프로그램을 실행한 후 출력은 다음과 같아야 합니다: [-9, -7, -1, 0, 2, 6, 8].
비수치 요소의 배열을 정렬하여 다른 테스트를 생성합니다. 문자열 배열을 선언합니다. mergeSort() 메서드를 호출하고 배열을 인수로 전달합니다. 마지막으로, 정렬된 배열을 콘솔에 출력합니다. 이 단계의 코드 블록은 다음과 같습니다.
String[] strsToSort = {"John", "David", "Emily", "Bob", "Christine"};
mergeSort(strsToSort, 0, strsToSort.length - 1);
System.out.println(Arrays.toString(strsToSort));
프로그램을 실행한 후 출력은 다음과 같아야 합니다: ['Bob', 'Christine', 'David', 'Emily', 'John'].
다음은 병합 정렬 (Merge Sort) 의 최종 소스 코드입니다.
import java.util.Arrays;
public class MergeSort {
public static void mergeSort(int[] arrToSort, int startIdx, int endIdx) {
if (startIdx >= endIdx) {
return;
}
int midIdx = startIdx + (endIdx - startIdx) / 2;
mergeSort(arrToSort, startIdx, midIdx);
mergeSort(arrToSort, midIdx + 1, endIdx);
merge(arrToSort, startIdx, midIdx, endIdx);
}
public static void merge(int[] arrToSort, int startIdx, int midIdx, int endIdx) {
int[] leftArr = new int[midIdx - startIdx + 1];
int[] rightArr = new int[endIdx - midIdx];
for (int i = 0; i < leftArr.length; i++) {
leftArr[i] = arrToSort[startIdx + i];
}
for (int i = 0; i < rightArr.length; i++) {
rightArr[i] = arrToSort[midIdx + i + 1];
}
int leftArrIdx = 0, rightArrIdx = 0, sortedArrIdx = startIdx;
while ((leftArrIdx < leftArr.length) && (rightArrIdx < rightArr.length)) {
if (leftArr[leftArrIdx] < rightArr[rightArrIdx]) {
arrToSort[sortedArrIdx] = leftArr[leftArrIdx];
leftArrIdx += 1;
} else {
arrToSort[sortedArrIdx] = rightArr[rightArrIdx];
rightArrIdx += 1;
}
sortedArrIdx += 1;
}
while (leftArrIdx < leftArr.length) {
arrToSort[sortedArrIdx] = leftArr[leftArrIdx];
leftArrIdx += 1;
sortedArrIdx += 1;
}
while (rightArrIdx < rightArr.length) {
arrToSort[sortedArrIdx] = rightArr[rightArrIdx];
rightArrIdx += 1;
sortedArrIdx += 1;
}
}
public static void main(String[] args) {
//create an unsorted integer array
int[] arrToSort = { 4, 2, 8, 0, 1, 6 };
//sort the integer array using Merge Sort
mergeSort(arrToSort, 0, arrToSort.length - 1);
//print the sorted array
System.out.println(Arrays.toString(arrToSort));
//create an empty integer array
int[] emptyArr = {};
//sort the empty array
mergeSort(emptyArr, 0, emptyArr.length - 1);
//print the sorted array
System.out.println(Arrays.toString(emptyArr));
//create a single-element array
int[] singleElementArr = {7};
//sort the single-element array
mergeSort(singleElementArr, 0, singleElementArr.length - 1);
//print the sorted array
System.out.println(Arrays.toString(singleElementArr));
//create a negative integer array
int[] arrWithNegatives = {-7, 2, -9, 0, -1, 6, 8};
//sort the negative integer array
mergeSort(arrWithNegatives, 0, arrWithNegatives.length - 1);
//print the sorted array
System.out.println(Arrays.toString(arrWithNegatives));
//create a string array
String[] strsToSort = {"John", "David", "Emily", "Bob", "Christine"};
//sort the string array
mergeSort(strsToSort, 0, strsToSort.length - 1);
//print the sorted array
System.out.println(Arrays.toString(strsToSort));
}
}
터미널을 사용하여 프로그램을 컴파일하고 실행합니다:
javac MergeSort.java && java MergeSort
이 랩에서는 병합 정렬 (Merge Sort) 이 무엇인지, 어떻게 작동하는지, 그리고 Java 에서 어떻게 구현하는지 배웠습니다. 입력 배열을 분할하고 병합하기 위해 각각 mergeSort()와 merge()라는 두 개의 public static 메서드를 만들었습니다. 구현 후, 다양한 입력에 대해 테스트하고, 시간 및 공간 복잡도를 논의했으며, 기능성을 검증했습니다. 축하합니다! Java 에서 병합 정렬 랩을 성공적으로 완료했습니다.