์๋ ํ์ธ์, ์๊ณ ๋ฆฌ์ฆ์ ์ ๋ฆฌํ๋ ํฌ์คํ ์ ๋๋ค. ๋ค๋ฅธ ์๊ณ ๋ฆฌ์ฆ์ ์ฐธ๊ณ ํ์๋ ค๋ฉด ํด๋น ์นดํ ๊ณ ๋ฆฌ๋ฅผ ์ด์ฉํด์ฃผ์ธ์. ๐
๋ถํ ์ ๋ณต (Merge Sort)
Merge Sort, ๋ถํ ์ ๋ณต, ๋ณํฉ ์ ๋ ฌ, ํฉ๋ณ ์ ๋ ฌ ์ด๋ผ๊ณ ๋ ํ๋ค. ์๊ฐ๋ณต์ก๋๋ ์ต์ ์ ์ํฉ๊น์ง๋ O(n log n)์ ๋ณด์ฅํ๋ค.
๋๋ ์ด ์๊ณ ๋ฆฌ์ฆ์ ๊ณต๋ถํ ๋, ๋ถํ ์ ๋ณต์ด๋ผ๊ณ ๋ฐฐ์์ ๋ถํ ์ ๋ณต์ด๋ผ๊ณ ์นญํ๊ฒ ๋ค.
๊ทธ๋ ๋ค๋ฉด ์ ๋ถํ ์ ๋ณต์ผ๊น?
Merge Sort๊ฐ O(n logn)์ ๋ณด์ฅํ ์ ์์๋ ์ด์ ๋ ์ ๋ ฌ ํ ๋ฐฐ์ด์ ๋ฐ์ผ๋ก ๋ถํ ํ๋ค ๊ฐ๊ฐ ์ ๋ ฌ ์ํค๊ณ ํฉ์น๊ธฐ ๋๋ฌธ์ ์๋๊ฐ ๋น ๋ฅด๋ค๊ณ ํ ์ ์๋ค. (์๋์ ์ด๋ฏธ์ง๋ฅผ ๋ณด์)
๋ฐฐ์ด์ ๋ฐ์ผ๋ก ์๋ฅด๊ณ , ๊ทธ ์๋ฅธ ๋ฐฐ์ด์ ๋ ๋ฐ์ผ๋ก ์๋ฅด๊ณ , ๊ทธ๋ ๊ฒ ํผ์๊ฐ ๋ ๋๊น์ง ๋ถํ ์ํจ๋ค.
๋ญ๊ฐ ๋ฐ๋ณต์ ์ธ ๊ณผ์ ์ด ๋ณด์ธ๋ค. ์ด ์ ๋ ฌ์ ์ฌ๊ท๋ก ํํ ํ ์ ์๋ค.
๊ฐ ์ฒ๋ฆฌ ํ๋ ์์๋ฅผ ๋ฒํธ๋ก ํ์ ํด๋ดค๋ค.
๊ทธ๋ผ ๊ฐ ์์๋๋ก ์ฒ๋ฆฌ ํ๋ ๊ณผ์ ์ ์ดํด ๋ณด์.
- mergeSort(arr, 0, 5);
middle์ ๋จผ์ ๊ตฌํ๋ค. middle = (0 + 5) / 2 --> 2
๊ทธ๋ผ ๋๋ฒ ๋๋ ์ ์ฌ๊ท ํธ์ถ์ ํ๋ค.
- mergeSort(arr, 0, middle);
- mergeSort(arr, middle+1, 5);
- 1. mergeSort(arr, 0, 2);
int m = 0;
int n = 2;
int middle = (m+n) / 2; // 1
- mergeSort(arr, m, middle); // recursion (arr, 0, 1)
- mergeSort(arr, middle+1, n); // recursion (arr, 2, 2)
- 2. mergeSort(arr, 0, 1);
int m = 0;
int n = 1;
int middle = (m+n) / 2; // 0
- mergeSort(arr, m, middle); // recursion (arr, 0, 0)
- mergeSort(arr, middle+1, n); // recursion (arr, 1, 1)
- 3. mergeSort(arr, 0, 0);
int m = 0;
int n = 0;
int middle = (m+n) / 2; // 0
ํธ์ถ ํ ํ์๊ฐ ์๋ค!
- 4. mergeSort(arr, 1, 1);
int m = 0;
int n = 0;
int middle = (m+n) / 2; // 0
๋ง์ฐฌ๊ฐ์ง๋ก ํธ์ถ ํ ํ์๊ฐ ์๋ค!
์ฌ๊ธฐ์ ์ ์ ์๋ ์กฐ๊ฑด mergeSort ํธ์ถ ์ m == n์ผ ๊ฒฝ์ฐ ํธ์ถ ํ ํ์์๋ค. ( m < n ) ์ธ ๊ฒฝ์ฐ๋ง ํธ์ถํ๋ฉด ๋๋ค.
- 5. mergeSort(arr, 2, 2); -> ํธ์ถ X
- 6. mergeSort(arr, 3, 5);- > 3,4/5,5 ํธ์ถ
- 7. mergeSort(arr, 3, 4); -> 3,3/4,4 ํธ์ถ
- 8. mergeSort(arr, 3, 3); -> ํธ์ถ X
- 9. mergeSort(arr, 4, 4); -> ํธ์ถ X
- 10. mergeSort(arr, 5, 5); -> ํธ์ถ X
- 7. mergeSort(arr, 3, 4); -> 3,3/4,4 ํธ์ถ
์ ์ฌ๊ธฐ๊น์ง ๋ถํ ํ๋ ๊ณผ์ ์ ์ดํด๋ณด์๋๋ฐ, ์ฝ๋๋ก ๋ํ๋ด๋ฉด ์๋์ ๊ฐ๋ค.
public void mergeSort(int[] arr, int m, int n) {
if(m < n) {
int middle = (m + n) / 2;
mergeSort(arr, m, middle);
mergeSort(arr, middle + 1, n);
}
}
์ด์ ๋ถํ ์ ๋ณต์์ ์ ๋ณต ๊ณผ์ , ์ฆ ํฉ์น๋ฉด์ ์ ๋ ฌ ์ํค๋ ๊ณผ์ ์ ์ดํด๋ณด์.
์ด 5๋ฒ์ ๊ฑธ์ณ์ ์ ๋ณต ๊ณผ์ ์ด ์ด๋ฃจ์ด ์งํ ๋ฐ, ๊ทธ ๊ณผ์ ์ ํ๋ฒ ํ๋์ฉ ๋ณด๊ฒ ๋ค.
- 1. merge(arr, 0, 1)
์ธ์ ๊ฐ์ผ๋ก arr๋ฐฐ์ด์ ์ฃผ์์, ์์ ์ธ๋ฑ์ค, ๋ง์ง๋ง ์ธ๋ฑ์ค ๋ฅผ ๋๊ฒจ์ค๋ค.
๊ฐ ์ธ๋ฑ์ค์ ๊ฐ๋ค์ ๋น๊ตํ๋ฉด์ sorted ๋ฐฐ์ด์๋ค๊ฐ ๋ฃ๋๋ค.
- 2. merge(arr, 0, 2)
์ด์ ์ง๊ธ์ด ์ค์ํ๋ค. ์์ ์ ๋ ฌ๋ ๋๊ฐ์ ์ธ๋ฑ์ค์ arr[2] ๋ฅผ ๋น๊ตํด์ sorted์ ๋ฃ์ด์ผ ํ๋๋ฐ
์์ ๋ฐฐ์ด์ ์ด๋ฏธ ์ ๋ ฌ๋ ์ํ์ด๊ธฐ ๋๋ฌธ์, for๋ฌธ์ผ๋ก ๋น๊ตํ sorted์ ๋ฃ์ด์ฃผ๋ฉด ๋๋ค.
๋น๊ตํ ๊ฐ์ ๋ฃ์ด์ฃผ๊ณ , ํด์ค์ผ ํ ๊ฒ์ด k๊ฐ ์ฆ๊ฐ, ๋ฃ์ ์ธ๋ฑ์ค ๊ฐ ์ฆ๊ฐ ์ํค๊ธฐ. ์์ ๊ทธ๋ฆผ์ k++, j++ ๋ฅผ ํด์ฃผ๋ฉด ๋๋ค.
๊ทธ์น๋ง, ์กฐ์ฌํด์ผ ํ ๊ฒ์ด j++ ๋ฅผ ํด์ฃผ๋ฉด ์ธ๋ฑ์ค๊ฐ ๋ฒ์ด๋๊ฒ ๋๋ค.
๊ทธ๋์ ์ฐ๋ฆฌ๊ฐ ์ค์ ํด์ค์ผ ํ ์กฐ๊ฑด์ ( i <= middle && j <= n ) ์ด๋ค.
์ฝ๋๋ก ์์ฑํด๋ณด๋ฉด,
while (i <= middle && j <= n) {
if (a[i] < a[j]) {
sorted[k] = a[i];
i++;
}else{
sorted[k] = a[j];
j++;
}
k++;
}
์ ๊ทธ ๋ค์ ํด์ผ ํ ๊ฒ์ด ๋ฌด์์ผ๊น?
while๋ฌธ์ด ์ข ๋ฃ๋๋ฉด, ์์ง ๋จ์ ์๋ ๋ฐ์ดํฐ๊ฐ ์๋ค๋ ๋ป์ด๋ค. ๊ทธ์ ๋์์ ํ์ชฝ์ ์ด๋ฏธ ๋ค ์ฎ๊ฒผ๊ณ , ๋๋จธ์ง ํ์ชฝ๋ง ๋ฐ๋ณต๋ฌธ์ ํตํด ๋ฃ์ด์ฃผ๊ธฐ๋ง ํ๋ฉด ๋๋ค.
์ฝ๋๋ก ํจ๊ป ๋ณด์.
1. ๋ง์ฝ i๊ฐ middle๋ณด๋ค ์ปค์ก์ ๊ฒฝ์ฐ
if(i > middle) {
for(int t = j; t <= n; t++) {
sorted[k++] = arr[t];
}
}
2. ๋ง์ฝ j๊ฐ n๋ณด๋ค ์ปค์ก์ ๊ฒฝ์ฐ
if(j > n) {
for(int t = i; t <= middle; t++) {
sorted[k++] = arr[t];
}
}
๊ทธ ๋ค์์ sorted ๋ฐฐ์ด์ ๋ค์ arr ๋ฐฐ์ด๋ก ๋ฎ์ด์์ด ์ฃผ๋ฉด ๋๋ค!
for(int t=m; t <= n; t++) {
arr[t] = sorted[t];
}
์ ์ฒด ์ฝ๋
public class Merge_Sort_Tutorial {
static int number = 8;
static int[] sorted = new int[8];
private static void merge(int[] a, int m, int middle, int n) {
int i = m;
int j = middle + 1;
int k = m;
// ๋ ๋ฐฐ์ด ์ค ํ๋๋ฅผ ๋ค ์ฎ๊ธธ ๋ ๊น์ง ๋ฐ๋ณต
while (i <= middle && j <= n) {
if (a[i] < a[j]) {
sorted[k] = a[i];
i++;
}else{
sorted[k] = a[j];
j++;
}
k++;
}
// ๋จ์์๋ ๋ฐ์ดํฐ ์ฝ์
if (i > middle) {
for (int t = j; t <= n; t++) {
sorted[k] = a[t];
k++;
}
}else{
for (int t = i; t <= middle; t++) {
sorted[k] = a[t];
k++;
}
}
// ์ ๋ ฌ๋ ๋ฐฐ์ด์ ์ฝ์
for (int t = m; t <= n; t++) {
a[t] = sorted[t];
}
}
private static void mergeSort(int[] a, int m, int n) {
if (m < n) {
int middle = (m + n) / 2;
mergeSort(a, m, middle);
mergeSort(a, middle + 1, n);
merge(a, m, middle, n);
}
}
public static void main(String[] args) {
int[] array = {7, 1, 5, 5, 8, 9, 3, 2};
mergeSort(array, 0 , array.length-1);
for (int i : array) {
System.out.print(i + ", ");
}
}
}