๐ŸŒป JAVA/์•Œ๊ณ ๋ฆฌ์ฆ˜, ์ž๋ฃŒ๊ตฌ์กฐ

์•Œ๊ณ ๋ฆฌ์ฆ˜ - Merge Sort (๋ถ„ํ•  ์ •๋ณต, ๋ณ‘ํ•ฉ ์ •๋ ฌ)

iseunghan 2020. 11. 16. 12:31
๋ฐ˜์‘ํ˜•

์•ˆ๋…•ํ•˜์„ธ์š”, ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ •๋ฆฌํ•˜๋Š” ํฌ์ŠคํŒ…์ž…๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ฐธ๊ณ ํ•˜์‹œ๋ ค๋ฉด ํ•ด๋‹น ์นดํ…Œ๊ณ ๋ฆฌ๋ฅผ ์ด์šฉํ•ด์ฃผ์„ธ์š”. ๐Ÿ˜Š

 

'๐ŸŒป JAVA/์•Œ๊ณ ๋ฆฌ์ฆ˜, ์ž๋ฃŒ๊ตฌ์กฐ' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๊ธ€ ๋ชฉ๋ก

๊ณต๋ถ€ํ•œ ๊ฒƒ๋“ค ์ •๋ฆฌํ•œ ๋‚ด์šฉ์„ ํฌ์ŠคํŒ…ํ•ฉ๋‹ˆ๋‹ค.

iseunghan.tistory.com

 

 

๋ถ„ํ•  ์ •๋ณต (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

 

์ž ์—ฌ๊ธฐ๊นŒ์ง€ ๋ถ„ํ•  ํ•˜๋Š” ๊ณผ์ •์„ ์‚ดํŽด๋ณด์•˜๋Š”๋ฐ, ์ฝ”๋“œ๋กœ ๋‚˜ํƒ€๋‚ด๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

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 + ", ");
        }
    }
}

 

๋ฐ˜์‘ํ˜•