[Algorithm] Quick Sort (Merge Sort ๋น„๊ต)

๊น€์ •๋ฏผยท2024๋…„ 3์›” 14์ผ
1
post-thumbnail

์ด์ „ ํฌ์ŠคํŠธ์—์„œ ํ•ฉ๋ณ‘ ์ •๋ ฌ์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์•˜๋‹ค.

์ด๋ฒˆ์—๋Š” ํ€ต ์ •๋ ฌ์„ ์•Œ์•„๋ณด๋ฉด์„œ ํ•ฉ๋ณ‘ ์ •๋ ฌ๊ณผ ์ฐจ์ด์ ์„ ์•Œ์•„๋ณด์ž.

ํ•ฉ๋ณ‘ ์ •๋ ฌ์—๋Œ€ํ•œ ์„ค๋ช…์€ ์ƒ๋žตํ•œ๋‹ค.

๐Ÿ’ก ํ€ต ์ •๋ ฌ Quick Sort

ํ•˜๋‚˜์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ํ”ผ๋ฒ—(pivot)์„ ๊ธฐ์ค€์œผ๋กœ ๋‘ ๊ฐœ์˜ ๋น„๊ท ๋“ฑํ•œ ํฌ๊ธฐ๋กœ ๋ถ„ํ• ํ•˜๊ณ  ๋ถ„ํ• ๋œ ๋ถ€๋ถ„ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ •๋ ฌํ•œ ๋‹ค์Œ, ๋‘ ๊ฐœ์˜ ์ •๋ ฌ๋œ ๋ถ€๋ถ„ ๋ฆฌ์ŠคํŠธ๋ฅผ ํ•ฉํ•˜์—ฌ ์ „์ฒด๊ฐ€ ์ •๋ ฌ๋œ ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋˜๊ฒŒ ํ•˜๋Š” ๋ฐฉ๋ฒ•

๐Ÿ”‘ ๋‹จ๊ณ„

๋ถ„ํ• (Divide): ์ž…๋ ฅ ๋ฐฐ์—ด์„ ํ”ผ๋ฒ—์„ ๊ธฐ์ค€์œผ๋กœ ๋น„๊ท ๋“ฑํ•˜๊ฒŒ 2๊ฐœ์˜ ๋ถ€๋ถ„ ๋ฐฐ์—ด(ํ”ผ๋ฒ—์„ ์ค‘์‹ฌ์œผ๋กœ ์™ผ์ชฝ: ํ”ผ๋ฒ—๋ณด๋‹ค ์ž‘์€ ์š”์†Œ๋“ค, ์˜ค๋ฅธ์ชฝ: ํ”ผ๋ฒ—๋ณด๋‹ค ํฐ ์š”์†Œ๋“ค)๋กœ ๋ถ„ํ• ํ•œ๋‹ค.

์ •๋ณต(Conquer): ๋ถ€๋ถ„ ๋ฐฐ์—ด์„ ์ •๋ ฌํ•œ๋‹ค. ๋ถ€๋ถ„ ๋ฐฐ์—ด์˜ ํฌ๊ธฐ๊ฐ€ ์ถฉ๋ถ„ํžˆ ์ž‘์ง€ ์•Š์œผ๋ฉด ์ˆœํ™˜ ํ˜ธ์ถœ ์„ ์ด์šฉํ•˜์—ฌ ๋‹ค์‹œ ๋ถ„ํ•  ์ •๋ณต ๋ฐฉ๋ฒ•์„ ์ ์šฉํ•œ๋‹ค.

๊ฒฐํ•ฉ(Combine): ์ •๋ ฌ๋œ ๋ถ€๋ถ„ ๋ฐฐ์—ด๋“ค์„ ํ•˜๋‚˜์˜ ๋ฐฐ์—ด์— ํ•ฉ๋ณ‘ํ•œ๋‹ค. ์ˆœํ™˜ ํ˜ธ์ถœ์ด ํ•œ๋ฒˆ ์ง„ํ–‰๋  ๋•Œ๋งˆ๋‹ค ์ตœ์†Œํ•œ ํ•˜๋‚˜์˜ ์›์†Œ(ํ”ผ๋ฒ—)๋Š” ์ตœ์ข…์ ์œผ๋กœ ์œ„์น˜๊ฐ€ ์ •ํ•ด์ง€๋ฏ€๋กœ, ์ด ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๋ฐ˜๋“œ์‹œ ๋๋‚œ๋‹ค๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ’Ž ์†Œ์Šค


public class Main {
  public static void main(String[] args) {

// list ์ดˆ๊ธฐํ™” (10๋งŒ ๊ฐœ์˜ ์–‘์ˆ˜)
    int[] list = new int[100000];
    Random random = new Random();
    for (int i = 0; i < list.length; i++) {
      list[i] = Math.abs(random.nextInt()); // ์Œ์ˆ˜๊ฐ€ ์•„๋‹Œ ๊ฐ’ ์ƒ์„ฑ
    }
    quickSortTest(list);

  }

  private static void quickSortTest(int[] list) {
    SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:ms");
    QuickSort quickSort = new QuickSort();

    Date now = new Date();
    String start = sdf1.format(now);

    quickSort.quickSort(list);

    Date now2 = new Date();
    String end = sdf1.format(now2);

    System.out.println("์‹œ์ž‘์‹œ๊ฐ„ quickSort : " + start);
    System.out.println("์ข…๋ฃŒ์‹œ๊ฐ„ quickSort : " + end);
    System.out.println("quickSort ๊ฑธ๋ฆฐ ์‹œ๊ฐ„ : " + (now2.getTime() - now.getTime()) / 1000.0 + "์ดˆ");
    System.out.println();
  }
}

class QuickSort {
  public void quickSort(int[] arr) {
    quickSort(arr, 0, arr.length - 1);
  }

  private void quickSort(int[] arr, int start, int end) {
    int part2 = partition(arr, start, end);
    if (start < part2 - 1) {
      quickSort(arr, start, part2 - 1);
    }
    if (part2 < end) {
      quickSort(arr, part2, end);
    }
  }

  private int partition(int[] arr, int start, int end) {
    int pivot = arr[(start + end) / 2];
    while (start <= end) {
      while (arr[start] < pivot) start++;
      while (arr[end] > pivot) end--;

      if (start <= end) {
        swap(arr, start, end);
        start++;
        end--;
      }
    }
    return start;
  }

  private void swap(int[] arr, int start, int end) {
    int temp = arr[start];
    arr[start] = arr[end];
    arr[end] = temp;
  }

}

๊ฒฐ๊ณผ

๋น„๊ต

quickSort, mergerSort, ์ž๋ฐ” ๊ธฐ๋ณธ Sort ์ด ์„ธ๊ฐ€์ง€๋ฅผ ๊ฐ€์ง€๊ณ  ๋น„๊ตํ•˜๊ณ ์ž ์•„๋ž˜์ฒ˜๋Ÿผ ์†Œ์Šค๋ฅผ ์ž‘์„ฑํ•˜์˜€๋‹ค.

์ด๋ฒˆ์— ์ž๋ฐ” ๊ธฐ๋ณธ Sort๊ฐ€ ํ€ต ์ •๋ ฌ์ด๋ผ๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋˜์–ด ๊ทธ๋ƒฅ ๊ฐ™์ด ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•ด ๋ณด์•˜๋‹ค.

๐Ÿ’Ž ์†Œ์Šค

public class Main {
public static void main(String[] args) {
    int size = 100000;

    int[] list = new int[size];
    Random random = new Random();
    for (int i = 0; i < list.length; i++) {
      list[i] = Math.abs(random.nextInt());
    }

    quickSortTest(list);

    int[] list2 = new int[size];
    Random random2 = new Random();
    for (int i = 0; i < list.length; i++) {
      list2[i] = Math.abs(random2.nextInt());
    }

    ArraySortTest(list2);

    int[] list3 = new int[size];
    Random random3 = new Random();
    for (int i = 0; i < list3.length; i++) {
      list3[i] = Math.abs(random3.nextInt());
    }

    mergeSortTest(list3);
  }

  private static void quickSortTest(int[] list) {
    SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:ms");
    QuickSort quickSort = new QuickSort();

    Date now = new Date();
    String start = sdf1.format(now);

    quickSort.quickSort(list);

    Date now2 = new Date();
    String end = sdf1.format(now2);

    System.out.println("์‹œ์ž‘์‹œ๊ฐ„ quickSort : " + start);
    System.out.println("์ข…๋ฃŒ์‹œ๊ฐ„ quickSort : " + end);
    System.out.println("quickSort ๊ฑธ๋ฆฐ ์‹œ๊ฐ„ : " + (now2.getTime() - now.getTime()) / 1000.0 + "์ดˆ");
    System.out.println();
  }

  private static void mergeSortTest(int[] list) {
    SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:ms");
    MergeSort mergeSort = new MergeSort();

    Date now = new Date();
    String start = sdf1.format(now);

    mergeSort.solution(list);

    Date now2 = new Date();
    String end = sdf1.format(now2);

    System.out.println("mergeSort ์‹œ์ž‘์‹œ๊ฐ„ : " + start);
    System.out.println("mergeSort ์ข…๋ฃŒ์‹œ๊ฐ„ : " + end);
    System.out.println("mergeSort ๊ฑธ๋ฆฐ ์‹œ๊ฐ„ : " + (now2.getTime() - now.getTime()) / 1000.0 + "์ดˆ");
    System.out.println();
  }

  private static void ArraySortTest(int[] list) {
    SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:ms");

    Date now = new Date();
    String start = sdf1.format(now);

    Arrays.sort(list);

    Date now2 = new Date();
    String end = sdf1.format(now2);

    System.out.println("ArraySort ์‹œ์ž‘์‹œ๊ฐ„ : " + start);
    System.out.println("ArraySort ์ข…๋ฃŒ์‹œ๊ฐ„ : " + end);
    System.out.println("ArraySort ๊ฑธ๋ฆฐ ์‹œ๊ฐ„ : " + (now2.getTime() - now.getTime()) / 1000.0 + "์ดˆ");
    System.out.println();
  }
}


class MergeSort {
  public int[] solution(int[] numList) {

    int size = numList.length - 1;
    mergeSort(numList, 0, size);
    return numList;
  }

  void mergeSort(int[] numList, int left, int right) {

    int mid = 0;

    if (left < right) {
      // (left+right)/2 ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•
      mid = left + (right - left) / 2;
      mergeSort(numList, left, mid);
      mergeSort(numList, mid + 1, right);
      merge(numList, left, mid, right);
    }
  }

  void merge(int[] list, int left, int mid, int right) {
    int[] sorted = new int[list.length];
    int i, j, k, l;
    i = left;
    j = mid + 1;
    k = left;

    /* ๋ถ„ํ•  ์ •๋ ฌ๋œ list์˜ ํ•ฉ๋ณ‘ */
    while (i <= mid && j <= right) {
      if (list[i] <= list[j])
        sorted[k++] = list[i++];
      else
        sorted[k++] = list[j++];
    }

    // ๋‚จ์•„ ์žˆ๋Š” ๊ฐ’๋“ค์„ ์ผ๊ด„ ๋ณต์‚ฌ
    if (i > mid) {
      for (l = j; l <= right; l++)
        sorted[k++] = list[l];
    }
    // ๋‚จ์•„ ์žˆ๋Š” ๊ฐ’๋“ค์„ ์ผ๊ด„ ๋ณต์‚ฌ
    else {
      for (l = i; l <= mid; l++)
        sorted[k++] = list[l];
    }

    // ๋ฐฐ์—ด sorted[](์ž„์‹œ ๋ฐฐ์—ด)์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐฐ์—ด list[]๋กœ ์žฌ๋ณต์‚ฌ
    for (l = left; l <= right; l++)
      System.arraycopy(sorted, left, list, left, right - left + 1);
  }
}


class QuickSort {
  public void quickSort(int[] arr) {
    quickSort(arr, 0, arr.length - 1);
  }

  private void quickSort(int[] arr, int start, int end) {
    int part2 = partition(arr, start, end);
    if (start < part2 - 1) {
      quickSort(arr, start, part2 - 1);
    }
    if (part2 < end) {
      quickSort(arr, part2, end);
    }
  }

  private int partition(int[] arr, int start, int end) {
    int pivot = arr[(start + end) / 2];
    while (start <= end) {
      while (arr[start] < pivot) start++;
      while (arr[end] > pivot) end--;

      if (start <= end) {
        swap(arr, start, end);
        start++;
        end--;
      }
    }
    return start;
  }

  private void swap(int[] arr, int start, int end) {
    int temp = arr[start];
    arr[start] = arr[end];
    arr[end] = temp;
  }

}

๊ฒฐ๊ณผ


๋งˆ๋ฌด๋ฆฌ

์ฒ˜์Œ ํ•ฉ๋ณ‘์ •๋ ฌ๊ณผ ํ€ต ์ •๋ ฌ์˜ ์ฐจ์ด๋Š” ๊ทธ๋ ‡๊ฒŒ ํฌ์ง€ ์•Š์„ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ์„ ํ•˜๊ณ  ์•ˆ์ •์ ์ธ ํ•ฉ๋ณ‘์ •๋ ฌ์„ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ์ƒ๊ฐ์„ ํ•˜๊ณ  ์žˆ์—ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ง์ ‘ ๋น„๊ตํ•ด ๋ณธ ๊ฒฐ๊ณผ ์ผ๋ฐ˜์ ์œผ๋กœ ํ€ต ์ •๋ ฌ์ด ๋” ๋น ๋ฅผ ๊ฒƒ์„ ํ™•์ธํ–ˆ๋‹ค. ์ƒํ™ฉ์— ๋”ฐ๋ผ์„œ ๋‹ค๋ฅด๊ฒŒ ์ •๋ ฌ์„ ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์€ ๋งž์ง€๋งŒ ์†”์งํžˆ ์•„์ง๊นŒ์ง€๋Š” ์ƒํ™ฉ์— ๋”ฐ๋ผ ์–ด๋–ค ์ •๋ ฌ์ด ์ ํ•ฉํ•œ์ง€ ํŒ๋‹จ์„ ํ•˜๊ธฐ์—” ๋ชจ์ž๋ž€๋‹ค๊ณ  ์ƒ๊ฐ์ด ๋“ ๋‹ค. 10๋งŒ ๊ฑด, 100๋งŒ ๊ฑด ๋ฐ์ดํ„ฐ๊ฐ€ ๋” ๋งŽ์•„์กŒ์„ ๋•Œ๋Š” ๋ณ‘ํ•ฉ ์ •๋ ฌ๊ณผ ํ€ต ์ •๋ ฌ์˜ ์ฐจ์ด๋Š” ๋”์šฑ๋” ์ปค์ง€๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์ด์ฒ˜๋Ÿผ ํ€ต ์ •๋ ฌ์ด ๊ต‰์žฅํžˆ ๋น ๋ฅธ ์†๋„๋ฅผ ๋ณด์—ฌ์ฃผ๊ณ  ์žˆ์–ด ์•ž์œผ๋กœ ํ€ต ์ •๋ ฌ์„ ์ž์ฃผ ์‚ฌ์šฉํ•  ๊ฒƒ ๊ฐ™๋‹ค. ์ž๋ฐ” ๊ธฐ๋ณธ Sort ํ•จ์ˆ˜๋Š” ํ€ต ์ •๋ ฌ ๊ธฐ๋ฐ˜์ด๋ฏ€๋กœ ์ง์ ‘ ํ€ต ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๊ตฌํ˜„ํ•ด์„œ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์ž๋ฐ” ๊ธฐ๋ณธ Sort๋กœ ์‚ฌ์šฉํ•˜๋ฉด ํŽธ๋ฆฌํ•  ๊ฒƒ ๊ฐ™๋‹ค.


์ถœ์ฒ˜ : https://www.youtube.com/watch?v=7BDzle2n47c - [์ž๋ฃŒ๊ตฌ์กฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜] ํ€ต์ •๋ ฌ(Quicksort)์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ณ  ์ž๋ฐ”๋กœ ๊ตฌํ˜„ํ•˜๊ธฐ - ์—”์ง€๋‹ˆ์–ด ๋Œ€ํ•œ๋ฏผ๊ตญ

์ถœ์ฒ˜ : https://gmlwjd9405.github.io/2018/05/10/algorithm-quick-sort.html - [์•Œ๊ณ ๋ฆฌ์ฆ˜] ํ€ต ์ •๋ ฌ(quick sort)์ด๋ž€

0๊ฐœ์˜ ๋Œ“๊ธ€