# ํ€ต ์ •๋ ฌ (Quick Sort)

written by sohyeon, hyemin ๐Ÿ’ก


# 1. ํ€ต ์ •๋ ฌ์ด๋ž€?

์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๋Š” ์•„์ฃผ ๋น ๋ฅธ ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค.
์ •๋ ฌ ์†๋„๊ฐ€ ๋น ๋ฅธ ๋ฐ์„œ ์ฐฉ์•ˆํ•ด ํ€ต ์ •๋ ฌ ์ด๋ผ๋Š” ์ด๋ฆ„์ด ๋ถ™์—ฌ์กŒ๋‹ค.
๋‹ค๋ฅธ ์›์†Œ์™€์˜ ๋น„๊ต๋งŒ์œผ๋กœ ์ •๋ ฌ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค.

# 2. ๋™์ž‘ ๋ฐฉ์‹

๋™์ž‘์„ ์ˆ˜ํ–‰ํ•  ๋•Œ ๊ฐ ๊ทธ๋ฃน์— ๋Œ€ํ•ด pivot์„ค์ •๊ณผ ๊ทธ๋ฃน ๋‚˜๋ˆ”์„ ๋ฐ˜๋ณตํ•˜๊ฒŒ ๋˜๋ฉฐ
๋ชจ๋“  ๊ทธ๋ฃน์ด 1๋ช…์ด ๋˜๋ฉด ์ •๋ ฌ์„ ๋งˆ์น˜๊ฒŒ ๋œ๋‹ค.

์ด ๊ณผ์ •์„ ๋ถ„ํ• ์ •๋ณต (Divide and Conquer)์ด๋ผ๊ณ  ํ•œ๋‹ค.

# 1) Divide and Conquer

  • Divide (PARTITION๊ณผ์ •)

    ์ •๋ ฌ ํ•ด์•ผ ํ•  ๋ฆฌ์ŠคํŠธ ์•ˆ์— ์žˆ๋Š” ํ•œ ์š”์†Œ๋ฅผ ์„ ํƒํ•ด pivot์œผ๋กœ ์ง€์ •,
    pivot์„ ๊ธฐ์ค€์œผ๋กœ ์ž‘์€ ์š”์†Œ๋“ค์„ ์™ผ์ชฝ, ํฐ ์š”์†Œ๋“ค์„ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์ด๋™

  • Conquer

    pivot์„ ์ œ์™ธํ•œ ์™ผ์ชฝ, ์˜ค๋ฅธ์ชฝ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋‹ค์‹œ ์ •๋ ฌ
    ๋ถ„ํ• ๋œ ๋ถ€๋ถ„ ๋ฆฌ์ŠคํŠธ์— ๋Œ€ํ•ด ๋‹ค์‹œ pivot์„ ์ง€์ •ํ•˜๊ณ 
    2๊ฐœ์˜ ๋ถ€๋ถ„๋ฆฌ์ŠคํŠธ๋กœ ๋‚˜๋ˆ„๋Š” ๊ณผ์ • ๋ฐ˜๋ณต

  • Pivot ์„ค์ •

# 2) ๋™์ž‘ ๊ณผ์ •

  • ์ž„์˜์˜ ํ•œ ์š”์†Œ๋ฅผ pivot์œผ๋กœ ์„ ํƒ
  • Pivot์„ ๊ธฐ์ค€์œผ๋กœ ์ž‘์€ ๊ฐ’์„ ์™ผ์ชฝ, ํฐ ๊ฐ’์„ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์ด๋™
  • Pivot์„ ์ œ์™ธํ•œ ์™ผ์ชฝ, ์˜ค๋ฅธ์ชฝ ๋ฆฌ์ŠคํŠธ์— partition๊ณผ์ • ๋ฐ˜๋ณต
  • ์œ„์˜ ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•ด ๊ฐ๊ฐ ๋ถ„ํ• ๋œ ๋ฆฌ์ŠคํŠธ์˜ ํฌ๊ธฐ๊ฐ€ 0์ด๋‚˜ 1์ด ๋˜๋ฉด ์ •๋ ฌ์ด ๋๋‚จ

# 3. ํŠน์ง•

# 1) ์žฅ์ 

  • ํ‰๊ท ์ ์œผ๋กœ ๋น ๋ฅธ ์ˆ˜ํ–‰ ์†๋„๋ฅผ ๊ฐ€์ง

# 2) ๋‹จ์ 

  • Unstableํ•œ ์ •๋ ฌ์ž„

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

์ž…๋ ฅ๋˜๋Š” ์ž๋ฃŒ์— ๋”ฐ๋ผ ์‹œ๊ฐ„๋ณต์žก๋„๊ฐ€ ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ๋‹ค.

# 1) Worst Case

์™„์ „ํ•˜๊ฒŒ ํ•œ์ชฝ์œผ๋กœ ๋ชฐ๋ ค ๊ทธ๋ฃน์ด ๋‚˜๋‰˜๋Š” ๊ฒฝ์šฐ,
left๊ฐ€ n-1๊ฐœ์˜ ์š”์†Œ๋ฅผ ๊ฐ–๊ณ  right๊ฐ€ 0๊ฐœ์˜ ์š”์†Œ๋ฅผ ๊ฐ€์งˆ ๋–„

T(n)=1+2+โ‹ฏ+n-1+n=n(n-1)/2
โˆดT(n)=O(n^2)

# 2) Best Case

pivot๊ฐ’์ด ๊ณ„์† ์ค‘์•™์— ์œ„์ฑ„ํ•ด left, right๊ฐ€ ๊ท ๋“ฑํ•˜๊ฒŒ ๋‚˜๋‰  ๋•Œ

T(n) = 2T(n/2)+O(n) ( O(n)์€ Divide๊ณผ์ • )
โˆดT(n)=O(nlog_2โกn)

# 3) Average Case

best case์— ๋ณดํ†ต ๊ฐ€๊นŒ์›€

  • ์ผ์ •ํ•œ ๋น„์œจ๋กœ ๋ถ„ํ•  ๋œ๋‹ค๋ฉด O(nlog_2โกn )์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋ฅผ ๊ฐ€์ง

  • ๊ทน๋‹จ์ ์ด๊ฒŒ ๋ถ„ํ• ๋˜๋Š” ๋น„์œจ์ด ์น˜์šฐ์นœ ๊ฒฝ์šฐ์—๋„ ๋™์ผํ•จ

์•„๋ž˜ ์ฆ๋ช…์— ์˜ํ•ด log_2n์œผ๋กœ ํ‘œํ˜„์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

๋”ฐ๋ผ์„œ T(n)์€ ์•„๋ž˜์™€ ๊ฐ™์ด ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค.

# 4. ์˜ˆ์ œ ์ฝ”๋“œ

import java.util.Scanner;
// ํ€ต ์ •๋ ฌ

class QuickSort {
	// ๋ฐฐ์—ด ์š”์†Œ a[idx1]๊ณผ a[idx2]์˜ ๊ฐ’์„ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.
	static void swap(int[] a, int idx1, int idx2) {
		int t = a[idx1];  a[idx1] = a[idx2];  a[idx2] = t;
	}

	// ํ€ต ์ •๋ ฌ
	static void quickSort(int[] a, int left, int right) {
		int pl = left;					// ์™ผ์ชฝ ์ปค์„œ
		int pr = right;					// ์˜ค๋ฅธ์ชฝ ์ปค์„œ
		int x = a[(pl + pr) / 2];		// ํ”ผ๋ฒ—

		do {
			while (a[pl] < x) pl++;
			while (a[pr] > x) pr--;
			if (pl <= pr)
				swap(a, pl++, pr--);
		} while (pl <= pr);

		if (left < pr)  quickSort(a, left, pr);
		if (pl < right) quickSort(a, pl, right);
	}

	public static void main(String[] args) {
		Scanner stdIn = new Scanner(System.in);

		System.out.println("ํ€ต ์ •๋ ฌ");
		System.out.print("์š”์†Ÿ์ˆ˜๏ผš");
		int nx = stdIn.nextInt();
		int[] x = new int[nx];

		for (int i = 0; i < nx; i++) {
			System.out.print("x[" + i + "]๏ผš");
			x[i] = stdIn.nextInt();
		}

		quickSort(x, 0, nx - 1);			// ๋ฐฐ์—ด x๋ฅผ ํ€ต ์ •๋ ฌ

		System.out.println("์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌํ–ˆ์Šต๋‹ˆ๋‹ค.");
		for (int i = 0; i < nx; i++)
			System.out.println("x[" + i + "]๏ผ" + x[i]);
	}
}
Last Updated: 12/5/2020, 11:36:44 AM