๐Ÿ“‚ ์ž๋ฃŒ๊ตฌ์กฐ/์ •๋ ฌ

ํ€ต ์ •๋ ฌ (Quick Sort)

Amenable 2023. 3. 20. 22:16

1. ์ •์˜ ๐Ÿ‘จโ€๐Ÿš€

ํ€ต ์ •๋ ฌ

  ํ€ต ์ •๋ ฌ(Quick Sort)์€ ๋ถ„ํ•  ์ •๋ณต ๋ฐฉ๋ฒ•์„ ์ด์šฉํ•˜๋Š” ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค. ํ€ต ์ •๋ ฌ์€ ํ”ผ๋ฒ—(Pivot)์„ ๊ธฐ์ค€์œผ๋กœ ๋ถ„ํ• ๊ณผ ์ •๋ณต์ด ์ด๋ฃจ์–ด์ง€๊ฒŒ ๋œ๋‹ค.

  ํ€ต ์ •๋ ฌ์€ 'ํ”ผ๋ฒ—์„ ์„ ํƒํ•˜๋Š” ๋ฐฉ์‹'๊ณผ '์žฌ๊ท€ ๋˜๋Š” ๋น„์žฌ๊ท€ ๋ฐฉ์‹'์˜ ์„ ํƒ์— ๋”ฐ๋ผ ๋‹ค์–‘ํ•œ ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์ด ์กด์žฌํ•œ๋‹ค. ์ด๋ฒˆ ๊ธ€์—์„œ๋Š” '์™ผ์ชฝ ํ”ผ๋ฒ—์„ ์„ ํƒํ•˜๋Š” ๋ฐฉ์‹'๊ณผ '์žฌ๊ท€ ๋ฐฉ์‹'์„ ํ†ตํ•œ ํ€ต ์ •๋ ฌ์„ ์•Œ์•„๋ณด๋„๋ก ํ•˜์ž.

 

2. ๋™์ž‘ ๋ฐฉ์‹ ๐Ÿฆธโ€โ™‚๏ธ

  ๊ธฐ๋ณธ์ ์ธ ๋™์ž‘ ๋ฐฉ์‹์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

  1. ๋ฐฐ์—ด์—์„œ ์ž„์˜์˜ ์›์†Œ์ธ pivot์„ ์„ ํƒํ•œ๋‹ค. (ํ•ด๋‹น ๊ธ€์—์„œ๋Š” ๋ฐฐ์—ด์—์„œ ์ œ์ผ ์™ผ์ชฝ ์›์†Œ๋ฅผ pivot์œผ๋กœ ์„ ํƒํ•œ๋‹ค.)
  2. pivot์„ ๊ธฐ์ค€์œผ๋กœ pivot๋ณด๋‹ค ์ž‘์€ ์›์†Œ๋Š” ์™ผ์ชฝ์œผ๋กœ, pivot๋ณด๋‹ค ํฐ ์›์†Œ๋Š” ์˜ค๋ฅธ์ชฝ์— ์˜ค๋„๋ก ๋ฐฐ์—ด์„ ๋ฐฐ์น˜ํ•œ๋‹ค.
  3. pivot์„ ๊ธฐ์ค€์œผ๋กœ ๋‚˜๋ˆ„์–ด์ง„ ์™ผ์ชฝ ๋ฐฐ์—ด๊ณผ ์˜ค๋ฅธ์ชฝ ๋ฐฐ์—ด์— 1~2๋ฒˆ์˜ ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•œ๋‹ค. (์žฌ๊ท€ ๋ฐฉ์‹์„ ์‚ฌ์šฉ)

  pivot์„ ๊ธฐ์ค€์œผ๋กœ '์–ด๋–ป๊ฒŒ pivot๋ณด๋‹ค ์ž‘์€ ์›์†Œ๋Š” ์™ผ์ชฝ์—, pivot๋ณด๋‹ค ํฐ ์›์†Œ๋Š” ์˜ค๋ฅธ์ชฝ์—' ์œ„์น˜ํ•˜๋„๋ก ํ•˜๋Š”์ง€ ์ž์„ธํžˆ ์•Œ์•„๋ณด์ž. ์™ผ์ชฝ์—์„œ ์‹œ์ž‘ํ•˜๋Š” ํฌ์ธํ„ฐ(lo)์™€ ์˜ค๋ฅธ์ชฝ์—์„œ ์‹œ์ž‘ํ•˜๋Š” ํฌ์ธํ„ฐ(hi)๋ฅผ ์ด์šฉํ•˜์—ฌ pivot์„ ๊ธฐ์ค€์œผ๋กœ ์›์†Œ๋“ค์„ ๋‚˜๋ˆ„๊ฒŒ ๋œ๋‹ค.

  1. hi์™€ lo๋ผ๋Š” ์ธ๋ฑ์Šค๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ๋ฅผ ์„ค์ •ํ•œ๋‹ค. (ํ”ํžˆ ์•Œ๊ณ  ์žˆ๋Š” ์‹ค์ œ ํฌ์ธํ„ฐ๊ฐ€ ์•„๋‹ˆ๋‹ค.)
  2. hi๋Š” pivot๋ณด๋‹ค ์ž‘์€ ๊ฐ’์„ ๋งŒ๋‚  ๋•Œ๊นŒ์ง€ ์™ผ์ชฝ์œผ๋กœ ์ด๋™ํ•œ๋‹ค.
  3. lo๋Š” pivot๋ณด๋‹ค ํฐ ๊ฐ’์„ ๋งŒ๋‚  ๋•Œ๊นŒ์ง€ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์ด๋™ํ•œ๋‹ค.
  4. ๋‘ ๊ฐœ์˜ ํฌ์ธํ„ฐ๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฐ’์„ ๋ฐ”๊พผ๋‹ค.
  5. lo๊ฐ€ hi๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์„ ๋•Œ๊นŒ์ง€ 2~5๋ฒˆ์„ ๋ฐ˜๋ณตํ•œ๋‹ค.
  6. pivot๊ณผ lo๋ฅผ ๋ฐ”๊ฟ”์ค€๋‹ค.

  {5, 3, 7, 8, 2, 4, 6}์˜ ๋ฐฐ์—ด์ด pivot์„ ๊ธฐ์ค€์œผ๋กœ ์–ด๋–ป๊ฒŒ ์ •๋ ฌ๋˜๋Š”์ง€ ๊ทธ๋ฆผ์„ ํ†ตํ•ด์„œ ์•Œ์•„๋ณด์ž.

  ๋งˆ์ง€๋ง‰์— pivot์ธ 5์™€ lo์ธ 2๋ฅผ ๋ฐ”๊ฟ”์ฃผ๋ฉด pivot์ธ 5๋Š” ์ž์‹ ์˜ ์ž๋ฆฌ์— ์ฐพ์•„๊ฐ„ ๊ฒƒ์ด ๋œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด pivot์„ ๊ธฐ์ค€์œผ๋กœ ์™ผ์ชฝ์—๋Š” pivot๋ณด๋‹ค ์ž‘์€ ์›์†Œ๋“ค์ด ์˜ค๋ฅธ์ชฝ์—๋Š” pivot๋ณด๋‹ค ํฐ ์›์†Œ๋“ค์ด ์œ„์น˜ํ•˜๊ฒŒ ๋œ๋‹ค.

  ๊ณ„์†ํ•ด์„œ pivot์„ ๊ธฐ์ค€์œผ๋กœ ์™ผ์ชฝ ์˜์—ญ๊ณผ ์˜ค๋ฅธ์ชฝ ์˜์—ญ์„ ์ •๋ ฌํ•ด ๋ณด์ž.

  ์ •๋ ฌ์ด ์ด๋ฃจ์–ด์ง€๋Š” ๊ณผ์ •์—์„œ 3๊ฐ€์ง€๋งŒ ์ฃผ๋ชฉํ•˜๋ฉด ์‰ฝ๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋‹ค.

  1. hi์™€ lo๊ฐ€ pivot๋ณด๋‹ค ์ž‘์€ ๊ฒƒ์„ ์ฐพ์„ ๋•Œ๊นŒ์ง€, pivot๋ณด๋‹ค ํฐ ๊ฐ’์„ ์ฐพ์„ ๋•Œ๊นŒ์ง€ ์ด๋™ํ•œ๋‹ค.
  2. lo๋Š” hi๋ณด๋‹ค ํฐ ์ธ๋ฑ์Šค๋ฅผ ๊ฐ€๋ฆฌํ‚ค์ง€ ์•Š๋Š”๋‹ค.
  3. ๋” ์ด์ƒ ์›€์ง์ผ ์ˆ˜ ์—†์œผ๋ฉด pivot๊ณผ lo๋ฅผ ๊ต์ฒดํ•œ๋‹ค.  

์ด๋ ‡๊ฒŒ ๋‚˜๋ˆ„์–ด์ง„ ๋ฐฐ์—ด๋“ค์„ ํ•ฉ์น˜๊ฒŒ ๋˜๋ฉด ์ •๋ ฌ๋œ ๋ฐฐ์—ด์ด ๋œ๋‹ค.

 

3. ๊ตฌํ˜„(JAVA) ๐Ÿง™โ€โ™‚๏ธ

public static void main(String[] args) {
    int[] array = {5, 3, 7, 8, 2, 4, 6};

    quickSort(array, 0, array.length - 1);
}

static void quickSort(int[] array, int left, int right) {
    if(left >= right)
        return;

    // pivot์„ ๊ธฐ์ค€์œผ๋กœ 
    // ์™ผ์ชฝ์—๋Š” pivot๋ณด๋‹ค ์ž‘์€ ๊ฒƒ๋“ค์ด
    // ์˜ค๋ฅธ์ชฝ์—๋Š” pivot๋ณด๋‹ค ํฐ ๊ฒƒ๋“ค์ด
    // ์œ„์น˜ํ•˜๋„๋ก ํ•˜๋Š” ๊ฒƒ
    int pivot = partition(array, left, right);

    // ์™ผ์ชฝ ์˜์—ญ์— ๋Œ€ํ•ด์„œ ๋‹ค์‹œ ์ •๋ ฌ
    quickSort(array, left, pivot - 1);
    // ์˜ค๋ฅธ์ชฝ ์˜์—ญ์— ๋Œ€ํ•ด์„œ ๋‹ค์‹œ ์ •๋ ฌ
    quickSort(array, pivot + 1, right);
}

static int partition(int[] array, int left, int right) {

    int pivot = array[left];
    int lo = left, hi = right;


    while(lo < hi) {

        // hi๊ฐ€ pivot๋ณด๋‹ค ์ž‘์€ ๊ฒƒ์„ ์ฐพ์„ ๋•Œ๊นŒ์ง€ ์™ผ์ชฝ์œผ๋กœ ์ด๋™
        while(pivot < array[hi]) {
            hi--;
        }

        // lo๊ฐ€ pivot๋ณด๋‹ค ํฐ ๊ฒƒ์„ ์ฐพ์„ ๋•Œ๊นŒ์ง€ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์ด๋™
        // lo๋Š” hi๋ณด๋‹ค ํฐ ์ธ๋ฑ์Šค ๊ฐ’์„ ๊ฐ€์งˆ ์ˆ˜ ์—†๋‹ค!!
        while(lo < hi && pivot >= array[lo]) {
            lo++;
        }

        // lo๊ฐ€ ๊ฐ€๋ฅดํ‚ค๋Š” ๊ฒƒ๊ณผ hi๊ฐ€ ๊ฐ€๋ฅดํ‚ค๋Š” ๊ฒƒ์„ ๊ต์ฒด
        swap(array, lo, hi);
    }

    // pivot๊ณผ lo๋ฅผ ๊ต์ฒด
    // ๊ต์ฒดํ•˜๊ฒŒ ๋˜๋ฉด pivot์„ ๊ธฐ์ค€์œผ๋กœ ์™ผ์ชฝ์—๋Š” ์ž‘์€ ๊ฐ’
    // ์˜ค๋ฅธ์ชฝ์—๋Š” ํฐ ๊ฐ’๋“ค์ด ์œ„์น˜ํ•จ.
    array[left] = array[lo];
    array[lo] = pivot;

    // pivot์˜ ์œ„์น˜๋ฅผ return
    return lo;
}

private static void swap(int[] array, int i, int j) {
    int temp = array[i];
    array[i] = array[j];
    array[j] = temp;
}

 

4. ์‹œ๊ฐ„๋ณต์žก๋„ & ๊ณต๊ฐ„๋ณต์žก๋„ ๐Ÿฆนโ€โ™‚๏ธ

1. ์‹œ๊ฐ„๋ณต์žก๋„

  ํ€ต ์ •๋ ฌ์˜ ์‹œ๊ฐ„๋ณต์žก๋„๋Š” pivot์ด ์–ด๋–ป๊ฒŒ ์„ ํƒ๋˜๋Š”์ง€์— ๋”ฐ๋ผ์„œ ๋‹ฌ๋ผ์ง„๋‹ค.

  ์ผ๋ฐ˜์ ์œผ๋กœ N๊ฐœ์˜ ๋…ธ๋“œ์— ๋Œ€ํ•˜์—ฌ ์ด์ง„ํŠธ๋ฆฌ์˜ ๋†’์ด๋Š” logN์ด ๋˜๊ณ  ๊ฐ ๋ ˆ๋ฒจ์—์„œ N๋ฒˆ์˜ ๋น„๊ต์™€ ์ •๋ ฌ์ด ์ผ์–ด๋‚œ๋‹ค. (๋ณ‘ํ•ฉ ์ •๋ ฌ ์ฐธ๊ณ ) ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์ผ๋ฐ˜์ ์ธ ์ƒํ™ฉ์—์„œ์˜ ์‹œ๊ฐ„๋ณต์žก๋„๋Š” O(N logN)์ด ๋œ๋‹ค.

  ํ•˜์ง€๋งŒ ์ตœ์•…์˜ ๊ฒฝ์šฐ๋Š” ์–˜๊ธฐ๊ฐ€ ๋‹ฌ๋ผ์ง„๋‹ค. pivot์ด ๊ณ„์†ํ•ด์„œ ๊ฐ€์žฅ ์ž‘์€ ๊ฐ’์ด๋‚˜ ํฐ ๊ฐ’์ด ๋˜๋ฉด(์ด๋ฏธ ์˜ค๋ฆ„์ฐจ์ˆœ์ด๋‚˜ ๋‚ด๋ฆผ์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌ์ด ๋˜์–ด ์žˆ๋Š” ๊ฒฝ์šฐ) ํŠธ๋ฆฌ์˜ ๋†’์ด logN์ด ์•„๋‹Œ N์ด ๋˜๊ฒŒ ๋œ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ ์ตœ์•…์˜ ๊ฒฝ์šฐ ์‹œ๊ฐ„๋ณต์žก๋„๋Š” O(N^2)๊ฐ€ ๋œ๋‹ค.

  ์ตœ์„ (BEST) ํ‰๊ท (AVERAGE) ์ตœ์•…(WORST)
์‹œ๊ฐ„๋ณต์žก๋„ O(N logN) O(N logN) O(N^2)

2. ๊ณต๊ฐ„๋ณต์žก๋„

  ๊ณต๊ฐ„๋ณต์žก๋„์˜ ๊ฒฝ์šฐ ์ฃผ์–ด์ง„ ๋ฐฐ์—ด ์•ˆ์—์„œ ๊ตํ™˜(swap)์ด ์ผ์–ด๋‚˜๋ฏ€๋กœ O(N)์ด๋‹ค.

 

5. ์žฅ์  & ๋‹จ์  ๐Ÿ‘จโ€๐Ÿ”ฌ

1. ์žฅ์ 

  • ์‹œ๊ฐ„๋ณต์žก๋„๊ฐ€ O(N logN)์ธ ๋‹ค๋ฅธ ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ๋น„ํ•ด ์ƒ๋Œ€์ ์œผ๋กœ ๋น ๋ฅด๋‹ค. (ํ•œ๋ฒˆ ๊ฒฐ์ •๋œ pivot์ด ๋‹ค์Œ ์—ฐ์‚ฐ์—์„œ ์ œ์™ธ๋œ๋‹ค๋Š” ํŠน์„ฑ ๋•Œ๋ฌธ)
  • ์ถ”๊ฐ€์ ์ธ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ํ•„์š”๋กœ ํ•˜์ง€ ์•Š๋Š”๋‹ค.

2. ๋‹จ์ 

  • ํŠน์ • ์กฐ๊ฑด์—์„œ ์„ฑ๋Šฅ์ด ๊ธ‰๊ฒฉํžˆ ๋–จ์–ด์ง„๋‹ค.
    pivot์„ ๊ฐ€์žฅ ์ž‘์€ ๊ฐ’์„ ์„ ํƒํ•˜๊ฑฐ๋‚˜ ํฐ ๊ฐ’์„ ๊ณ„์†ํ•ด์„œ ์„ ํƒํ•˜์—ฌ ๋ถˆ๊ท ํ˜• ๋ถ„ํ• ์ด ์ด๋ฃจ์–ด์ง€๋Š” ๊ฒฝ์šฐ
  • ์žฌ๊ท€๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ผ์ • ํšŸ์ˆ˜ ์ด์ƒ์ด๋ฉด ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•œ๋‹ค. (์žฌ๊ท€๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๊ธด ํ•œ๋ฐ ๋ณต์žกํ•˜๋‹ค.)

 

ํ•ด๋‹น ๊ธ€์€
Gyoogle๋‹˜์˜ ํ€ต ์ •๋ ฌ(Quick Sort),
Stranger๋‹˜์˜ ์ž๋ฐ”-ํ€ต ์ •๋ ฌ(Quick Sort)
๋ฅผ ์ฐธ๊ณ ํ•˜์˜€์Šต๋‹ˆ๋‹ค.