๋ฐ˜์‘ํ˜•

ํ€ต ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ฐœ๋…


ํ€ต ์ •๋ ฌ์€ ๋ถ„ํ•  ์ •๋ณต ์•Œ๊ณ ๋ฆฌ์ฆ˜(๋ฌธ์ œ๋ฅผ ๋” ์ž‘์€ 2๊ฐœ์˜ ๋ฌธ์ œ๋กœ ๋ถ„๋ฆฌํ•ด์„œ ํ•ด๊ฒฐํ•œ ํ›„ ๊ฒฐ๊ณผ๋ฅผ ๋ชจ์•„์„œ ์›๋ž˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•)์˜ ํ•˜๋‚˜๋กœ ์ฐฐ์Šค ์•คํ„ฐ๋‹ˆ ๋ฆฌ์ฒ˜๋“œ ํ˜ธ์–ด(Charles Antony Richard Hoare)๊ธฐ์‚ฌ๊ฐ€ ๊ฐœ๋ฐœํ–ˆ๋‹ค. ๊ฐ€์žฅ ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ๋น ๋ฅธ ์ˆ˜ํ–‰ ์†๋„๊ฐ€ ํŠน์ง•์ด๋‹ค. ๊ธฐ๋ณธ์ ์ธ ํ€ต ์ •๋ ฌ์€ ์•„๋ž˜ 3๋‹จ๊ณ„๋ฅผ ๋ฐ˜๋ณตํ•˜๋ฉฐ ์ •๋ ฌํ•œ๋‹ค.

 

  1. ๊ธฐ์ค€(Pivot; ํ”ผ๋ฒ—) ์š”์†Œ ์„ ํƒ — ์ฃผ๋กœ ๋ฐฐ์—ด์˜ ์ค‘๊ฐ„ ์š”์†Œ๋ฅผ ๊ธฐ์ค€์œผ๋กœํ•จ
  2. ๊ธฐ์ค€ ์š”์†Œ๋ณด๋‹ค ์ž‘์€ ์š”์†Œ๋Š” ์™ผ์ชฝ์œผ๋กœ ์ด๋™, ๊ธฐ์ค€ ์š”์†Œ๋ณด๋‹ค ํฐ ์š”์†Œ๋Š” ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์ด๋™
  3. ์ด๋™์‹œํ‚จ ์™ผ์ชฝ / ์˜ค๋ฅธ์ชฝ ์š”์†Œ๋“ค์— ๋Œ€ํ•ด 1~2๋ฒˆ ์ž‘์—… ๋ฐ˜๋ณต

 

๊ตฌํ˜„


Basic Quick Sort

๐Ÿ’ก ๊ตฌํ˜„ํ•˜๊ธฐ ์‰ฝ์ง€๋งŒ ํ•ญ์ƒ ์ƒˆ๋กœ์šด left / right ๋ฐฐ์—ด์„ ์ƒ์„ฑํ•ด ๋น„๊ตํ•œ ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฏ€๋กœ ๋ฉ”๋ชจ๋ฆฌ ๋‚ญ๋น„ ์‹ฌํ•จ

Not in place ๋ฐฉ์‹ : ์ถ”๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„ ํ•„์š” / ์ž…๋ ฅ๊ฐ’ ํด์ˆ˜๋ก ๋ฉ”๋ชจ๋ฆฌ ๋‚ญ๋น„ ์‹ฌํ•จ
Stable ๋ฐฉ์‹ : ์ค‘๋ณต ๋ฐ์ดํ„ฐ ์ˆœ์„œ ์•ˆ๋ฐ”๊ฟˆ

 

์ง„ํ–‰ ๊ณผ์ • ๋ถ„์„


๋”๋ณด๊ธฐ
โ‘ดf([85, 24, 63, 45, 17, 31, 96, 50])
=======================================
pivot = 45, arr = [85, 24, 63, 17, 31, 96, 50]
left = [24, 17, 31], right = [85, 63, 96, 50]
concat โ‘ตf([24, 17, 31]) + 45 + โ‘บf([85, 63, 96, 50])
---------------------------------------
return [17, 24, 31, 45, 50, 63, 85, 96]

โ‘ตf([24, 17, 31])
=======================================
pivot = 17, arr = [24, 31]
left = [], right = [24, 31]
concat โ‘ถ[] + 17 + โ‘ทf([24, 31])
---------------------------------------
return [17, 24, 31]

โ‘ทf([24, 31])
=======================================
pivot = 24, arr = [31]
left = [], right = [31]
concat โ‘ธ[] + 24 + โ‘นf([31])
---------------------------------------
return [24, 31]

โ‘บf([85, 63, 96, 50])
=======================================
pivot = 63, arr = [85, 96, 50]
left = [50], right = [85, 96]
concat โ‘ปf([50]) + 63 + โ‘ผf([85, 96])
---------------------------------------
return [50, 63, 85, 96]

โ‘ผf([85, 96]
=======================================
pivot = 85, arr = [96]
left = [], right = [96]
concat โ‘ฝ[] + 85 + โ‘พf([96])
---------------------------------------
return [85, 96]

 

  1. ๊ธฐ์ค€(Pivot; ํ”ผ๋ฒ—) ์š”์†Œ ์„ ํƒ
  2. ๊ธฐ์ค€ ์š”์†Œ๋ณด๋‹ค ์ž‘์€ ์š”์†Œ๋Š” left ๋ฐฐ์—ด์— ์ถ”๊ฐ€, ๊ธฐ์ค€ ์š”์†Œ๋ณด๋‹ค ํฐ ์š”์†Œ๋Š” right ๋ฐฐ์—ด์— ์ถ”๊ฐ€
  3. ๋ฐฐ์—ด ๊ธธ์ด๊ฐ€ 1์ด ๋ ๋•Œ๊นŒ์ง€ left, right ๋ฐฐ์—ด์— 1~2๋ฒˆ ์ž‘์—… ๋ฐ˜๋ณต

 

์ „์ฒด ์ฝ”๋“œ

// ์ฝ”๋“œ ์ฐธ๊ณ  GitHub @dragon-liu
const quickSort = (array) => {
  if (array.length <= 1) return array; // Base Case

  // ๋ฐฐ์—ด ๋ถ„ํ• ์„ ์œ„ํ•œ ๊ธฐ์ค€ ์š”์†Œ ์„ ํƒ ๋ฐ left, right ํ•˜์œ„ ๋ฐฐ์—ด ์ƒ์„ฑ
  const pivotIndex = Math.floor(array.length / 2);
  const pivot = array.splice(pivotIndex, 1)[0]; // ํ”ผ๋ฒ— ์š”์†Œ
  const left = [];
  const right = [];

  // ํ”ผ๋ฒ— ์š”์†Œ๋ณด๋‹ค ์ž‘์œผ๋ฉด left ํ•˜์œ„ ๋ฐฐ์—ด์— ์ถ”๊ฐ€, ํ”ผ๋ฒ— ์š”์†Œ๋ณด๋‹ค ํฌ๋ฉด right ํ•˜์œ„ ๋ฐฐ์—ด์— ์ถ”๊ฐ€
  for (let i = 0; i < array.length; i++) {
    if (array[i] < pivot) left.push(array[i]);
    else right.push(array[i]);
  }

  // ์ •๋ ฌ๋œ ๋ฐฐ์—ด์„ ์–ป๊ธฐ ์œ„ํ•ด ์žฌ๊ท€ ํ˜ธ์ถœ๋กœ ์œ„ ๊ณผ์ • ๋ฐ˜๋ณต
  return quickSort(left).concat(pivot, quickSort(right));
};

const sorted = quickSort([85, 24, 63, 45, 17, 31, 96, 50]);
console.log(sorted); // [17, 24, 31, 45, 50, 63, 85, 96]

 

In Place Quick Sort โญ๏ธ

In place ๋ฐฉ์‹ : ์ œ์ž๋ฆฌ ์ •๋ ฌ / ์ถ”๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„ ํ•„์š” ์—†์Œ
Unstable ๋ฐฉ์‹ : ์ค‘๋ณต ๋ฐ์ดํ„ฐ ์ˆœ์„œ ๋ฐ”๋€” ์ˆ˜ ์žˆ์Œ

 

์ง„ํ–‰ ๊ณผ์ • ๋ถ„์„

๋”๋ณด๊ธฐ

quickSort ํ•จ์ˆ˜ โ–ผ

โ‘ด Q([85, 24, 63, 45, 17, 31, 96, 50], 0, 7)
===========================================
b = P([85, 24, 63, 45, 17, 31, 96, 50], 0, 7) -> [P-1] = 4 | [31, 24, 17, 45, 63, 85, 96, 50]
โ‘ต Q([31, 24, 17, 45, 63, 85, 96, 50], 0, 3) -> [17, 24, 31, 45, 63, 85, 96, 50]
โ‘ผ Q([17, 24, 31, 45, 63, 85, 96, 50], 4, 7) -> [17, 24, 31, 45, 50, 63, 85, 96]
---------------------------------------
return [17, 24, 31, 45, 50, 63, 85, 96]

โ‘ต Q([31, 24, 17, 45, 63, 85, 96, 50], 0, 3)
===========================================
b = P([31, 24, 17, 45, 63, 85, 96, 50], 0, 3) -> [P-2] = 2 | [17, 24, 31, 45, 63, 85, 96, 50]
โ‘ถ Q([17, 24, 31, 45, 63, 85, 96, 50], 0, 1) -> [17, 24, 31, 45, 63, 85, 96, 50]
โ‘น Q([17, 24, 31, 45, 63, 85, 96, 50], 2, 3) -> [17, 24, 31, 45, 63, 85, 96, 50]
---------------------------------------
return [17, 24, 31, 45, 63, 85, 96, 50]

โ‘ถ Q([17, 24, 31, 45, 63, 85, 96, 50], 0, 1)
===========================================
b = P([17, 24, 31, 45, 63, 85, 96, 50], 0, 1) -> [P-3] = 1 | Swap ์—†์Œ
โ‘ท Q([17, 24, 31, 45, 63, 85, 96, 50], 0, 0) -> Base case return
โ‘ธ Q([17, 24, 31, 45, 63, 85, 96, 50], 1, 1) -> Base case return
---------------------------------------
return [17, 24, 31, 45, 63, 85, 96, 50] 

โ‘น Q([17, 24, 31, 45, 63, 85, 96, 50], 2, 3)
===========================================
b = P([17, 24, 31, 45, 63, 85, 96, 50], 2, 3) -> [P-4] = 3 | Swap ์—†์Œ
โ‘บ Q([17, 24, 31, 45, 63, 85, 96, 50], 2, 2) -> Base case return
โ‘ป Q([17, 24, 31, 45, 63, 85, 96, 50], 3, 3) -> Base case return
---------------------------------------
return [17, 24, 31, 45, 63, 85, 96, 50]

โ‘ผ Q([17, 24, 31, 45, 63, 85, 96, 50], 4, 7)
===========================================
b = P([17, 24, 31, 45, 63, 85, 96, 50], 4, 7) -> [P-5] = 6 | [17, 24, 31, 45, 63, 50, 96, 85]
โ‘ฝ Q([17, 24, 31, 45, 63, 50, 96, 85], 4, 5) -> [17, 24, 31, 45, 50, 63, 96, 85]
โ’€ Q([17, 24, 31, 45, 50, 63, 96, 85], 6, 7) -> [17, 24, 31, 45, 50, 63, 85, 96]
---------------------------------------
return [17, 24, 31, 45, 50, 63, 85, 96]

โ‘ฝ Q([17, 24, 31, 45, 63, 50, 96, 85], 4, 5)
===========================================
b = P([17, 24, 31, 45, 63, 50, 96, 85], 4, 5) -> [P-6] = 5 | [17, 24, 31, 45, 50, 63, 96, 85]
โ‘พ Q([17, 24, 31, 45, 50, 63, 96, 85], 4, 4) -> Base case return
โ‘ฟ Q([17, 24, 31, 45, 50, 63, 96, 85], 5, 5) -> Base case return
---------------------------------------
return [17, 24, 31, 45, 50, 63, 96, 85]

โ’€ Q([17, 24, 31, 45, 50, 63, 96, 85], 6, 7)
===========================================
b = P([17, 24, 31, 45, 50, 63, 96, 85], 6, 7) -> [P-7] = 7 | [17, 24, 31, 45, 50, 63, 85, 96]
โ’ Q([17, 24, 31, 45, 50, 63, 85, 96], 6, 6) -> Base case return
โ’‚ Q([17, 24, 31, 45, 50, 63, 85, 96], 7, 7) -> Base case return
---------------------------------------
return [17, 24, 31, 45, 50, 63, 85, 96]

 

๋ฐฐ์—ด์„ ๋‚˜๋ˆ„๋Š” ๊ธฐ์ค€ ์ธ๋ฑ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” partition ํ•จ์ˆ˜ / start, end ๋ฒ”์œ„ ๋‚ด์—์„œ ์ •๋ ฌ๋„ ์ด๋ค„์ง โ–ผ

[P-1] P([85, 24, 63, 45, 17, 31, 96, 50], 0, 7)
===============================================
pivot = 45, i = 0, j = 7
------------------------
while (0 <= 7)
85 < 45 (x) : i = 0
50 > 45 (-1) -> 96 > 45 (-1) -> 31 > 45 (x) : j = 5
if (0 <= 5) -> swap 85/31 -> [31, 24, 63, 45, 17, 85, 96, 50] -> i = 1, j = 4
------------------------
while (1 <= 4)
24 < 45 (+1) -> 63 < 45 (x) : i = 2
17 > 45 (x) : j = 4
if (2 <= 4) -> swap 63/17 -> [31, 24, 17, 45, 63, 85, 96, 50] -> i = 3, j = 3
------------------------
while (3 <= 3)
45 < 45 (x) : i = 3
45 > 45 (x) : j = 3
if (3 <= 3) -> swap 45/45 -> [31, 24, 17, 45, 63, 85, 96, 50] -> i = 4, j = 2
------------------------
return 4

[P-2] P([31, 24, 17, 45, 63, 85, 96, 50], 0, 3)
===============================================
pivot = 24, i = 0, j = 3
------------------------
while (0 <= 3)
31 < 24 (x) : i = 0
45 > 24 (-1) -> 17 > 24 (x) : j = 2
if (0 <= 2) -> swap 31/17 -> [17, 24, 31, 45, 63, 85, 96, 50] -> i = 1, j = 1
------------------------
while (1 <= 1)
24 < 24 (x) : i = 1
24 > 24 (x) : j = 1
if (1 <= 1) -> swap 24/24 -> [17, 24, 31, 45, 63, 85, 96, 50] -> i = 2, j = 0
------------------------
return 2

[P-3] P([17, 24, 31, 45, 63, 85, 96, 50], 0, 1)
===============================================
pivot = 17, i = 0, j = 1
------------------------
while (0 <= 1)
17 < 17 (x) : i = 0
24 > 17 (-1) -> 17 > 17 (x) : j = 0
if (0 <= 0) -> swap 17/17 -> [17, 24, 31, 45, 63, 85, 96, 50] -> i = 1, j = -1
------------------------
return 1

[P-4] P([17, 24, 31, 45, 63, 85, 96, 50], 2, 3)
===============================================
pivot = 31, i = 2, j = 3
------------------------
while (2 <= 3)
31 < 31 (x) : i = 2
45 > 31 (-1) -> 31 > 31 (x) : j = 2
if (2 <= 2) -> swap 31/31 -> [17, 24, 31, 45, 63, 85, 96, 50] -> i = 3, j = 1
------------------------
return 3

[P-5] P([17, 24, 31, 45, 63, 85, 96, 50], 4, 7)
===============================================
pivot = 85, i = 4, j = 7
------------------------
while (4 <= 7)
63 < 85 (+1) -> 85 < 85 (x) : i = 5
50 > 85 (x) -> j = 7
if (5 <= 7) -> swap 85/50 -> [17, 24, 31, 45, 63, 50, 96, 85] -> i = 6, j = 6
------------------------
while (6 <= 6)
96 < 85 (x) : i = 6
96 > 85 (-1) -> 50 > 85 (x) : j = 5
------------------------
return 6

[P-6] P([17, 24, 31, 45, 63, 50, 96, 85], 4, 5)
===============================================
pivot = 63, i = 4, j = 5
------------------------
while (4 <= 5)
63 < 63 (x) : i = 4
50 > 63 (x) : j = 5
if (4 <= 5) -> swap 63/50 -> [17, 24, 31, 45, 50, 63, 96, 85] -> i = 5, j = 4
------------------------
return 5

[P-7] P([17, 24, 31, 45, 50, 63, 96, 85], 6, 7)
===============================================
pivot = 96, i = 6, j = 7
------------------------
while (6 <= 7)
96 < 96 (x) : i = 6
85 > 96 (x) : j = 7
if (6 <= 7) -> swap 96/85 -> [17, 24, 31, 45, 50, 63, 85, 96] -> i = 7, j = 6
------------------------
return 7

 

๊ฒฝ๊ณ„ ์ธ๋ฑ์Šค ์ฐพ๊ธฐ / ํ”ผ๋ฒ— ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌ

 

  1. ์ฒ˜์Œ ํ˜ธ์ถœํ•  ๋• ๋ฐฐ์—ด ์ฒซ๋ฒˆ์งธ / ๋งˆ์ง€๋ง‰ ์ธ๋ฑ์Šค๋ฅผ ๊ฐ๊ฐ left(i), right(j)๋กœ ์„ค์ •
  2. left, right ์ธ๋ฑ์Šค๋ฅผ ๊ฒฝ๊ณ„๋กœ ๊ฐ€์šด๋ฐ ์š”์†Œ๋ฅผ ํ”ผ๋ฒ—์œผ๋กœ ์„ค์ •
    ex) const pivot = arr[Math.floor((start + end) / 2)]
  3. left ํฌ์ธํ„ฐ๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ์š”์†Œ์™€ ํ”ผ๋ฒ— ์š”์†Œ ๋น„๊ต
    • left ํฌ์ธํ„ฐ ์š”์†Œ๊ฐ€ ํ”ผ๋ฒ— ์š”์†Œ๋ณด๋‹ค ์ž‘์œผ๋ฉด ํฌ์ธํ„ฐ ์šฐ์ธก์œผ๋กœ ์ด๋™ (left ์ธ๋ฑ์Šค + 1)
    • ํ”ผ๋ฒ— ์š”์†Œ ๋ณด๋‹ค ๋” ํฐ ๊ฐ’์„ ์ฐพ์„๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณต
  4. right ํฌ์ธํ„ฐ๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ์š”์†Œ์™€ ํ”ผ๋ฒ— ์š”์†Œ ๋น„๊ต
    • right ํฌ์ธํ„ฐ ์š”์†Œ๊ฐ€ ํ”ผ๋ฒ— ์š”์†Œ๋ณด๋‹ค ํฌ๋ฉด ํฌ์ธํ„ฐ ์ขŒ์ธก์œผ๋กœ ์ด๋™ (right ์ธ๋ฑ์Šค - 1)
    • ํ”ผ๋ฒ— ์š”์†Œ ๋ณด๋‹ค ๋” ์ž‘์€ ๊ฐ’์„ ์ฐพ์„๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณต
  5. left, right ํฌ์ธํ„ฐ๊ฐ€ ๊ต์ฐจํ–ˆ๋Š”์ง€ ํ™•์ธ
    • ๊ต์ฐจ ์ „์ด๋ฉด(left < right)
      • ํ”ผ๋ฒ— ์™ผ์ชฝ์— ๋” ํฐ ๊ฐ’์ด ์žˆ๋Š” ์ƒํƒœ๋ฏ€๋กœ left โ‡„ right ์š”์†Œ ๊ตํ™˜(Swap)
      • ๋‹ค์Œ ๊ฒ€์ƒ‰์„ ์œ„ํ•ด left + 1, right - 1
    • ์ด๋ฏธ ๊ต์ฐจ ํ–ˆ์„ ๋•Œ๋„(left === right) ๊ฒฝ๊ณ„ ์ธ๋ฑ์Šค ์„ค์ •์„ ์œ„ํ•ด ์กฐ๊ฑด ํ†ต๊ณผ ํ›„ ์ธ๋ฑ์Šค ์ด๋™
  6. left๊ฐ€ right ๋ณด๋‹ค ์ปค์งˆ๋•Œ๊นŒ์ง€ 3~5 ๊ณผ์ • ๋ฐ˜๋ณต. ์ปค์กŒ๋‹ค๋ฉด left ๋ฐ˜ํ™˜ํ•˜๊ณ  ๊ฒฝ๊ณ„ ์ธ๋ฑ์Šค๋กœ ์‚ฌ์šฉ

 

๊ฒฝ๊ณ„ ์ธ๋ฑ์Šค๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋ฐฐ์—ด ๋ถ„ํ•  ํ›„ ์ˆœํ™˜ ํ˜ธ์ถœ

๐Ÿ’ก start์™€ end ์ธ๋ฑ์Šค๊ฐ€ ๊ฐ™์„๋•Œ๊นŒ์ง€ ์ž‘์—… ๋ฐ˜๋ณต

 

ๅณ partition ํ•จ์ˆ˜ ํ˜ธ์ถœ ํ›„ — start, end ๋ฒ”์œ„์•ˆ์—์„œ ์ •๋ ฌ ๋ฐ ๋‹ค์Œ ๊ฒฝ๊ณ„ ์ธ๋ฑ์Šค ๋ฐ˜ํ™˜

์ขŒ์ธก ๋ฐฐ์—ด : start(ํ•ญ์ƒ ๋™์ผ) ~ borderIndex - 1

// ๊ฒฝ๊ณ„ ์ธ๋ฑ์Šค ์ขŒ์ธก์˜ ๋ถ„ํ•  ๊ณผ์ •
// start 0 | end 7 | bdx 4 (borderIndex)
[1, 2, 3, 4, 5, 6, 7, 8] 
// start 0 | end 3 (์ด์ „ bdx - 1) | bdx 2
[1, 2, 3, 4, (5), (6), (7), (8)] 
// start 0 | end 1 (์ด์ „ bdx - 1) | bdx 1
[1, 2, (3), (4), (5), (6), (7), (8)] 
// start 0 | end 0 (์ด์ „ bdx - 1) -> start === end
[1, (2), (3), (4), (5), (6), (7), (8)]

 

์šฐ์ธก ๋ฐฐ์—ด : borderIndex ~ end(ํ•ญ์ƒ ๋™์ผ)

// ๊ฒฝ๊ณ„ ์ธ๋ฑ์Šค ์šฐ์ธก์˜ ๋ถ„ํ•  ๊ณผ์ •
// start 0 | end 7 | bdx 4 (borderIndex)
[1, 2, 3, 4, 5, 6, 7, 8]
// start 4 (์ด์ „ bdx) | end 7 | bdx 6
[(1), (2), (3), (4), 5, 6, 7, 8] 
// start 6 (์ด์ „ bdx) | end 7 | bdx 7
[(1), (2), (3), (4), (5), (6), 7, 8] 
// start 7 (์ด์ „ bdx) | end 7 -> start === end
[(1), (2), (3), (4), (5), (6), (7), 8]

 

์ „์ฒด ์ฝ”๋“œ


๋”๋ณด๊ธฐ
// ๋ฐฐ์—ด๊ณผ a, b ์ธ๋ฑ์Šค๋ฅผ ์ธ์ž๋กœ ๋ฐ›์•„ ๋ฐฐ์—ด[a] ๋ฐฐ์—ด[b] ์ˆœ์„œ๋ฅผ ๋ฐ”๊พธ๋Š” ํ•จ์ˆ˜
const swap = (arr, a, b) => {
  /* const temp = arr[a];
  arr[a] = arr[b];
  arr[b] = temp; */
  [arr[a], arr[b]] = [arr[b], arr[a]];
};
// Hoare ๋ถ„ํ•  ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•œ ํ€ต ์ •๋ ฌ - ์ฝ”๋“œ ์ฐธ๊ณ  https://bit.ly/3QjduFC
function quickSort(arr, start = 0, end = arr.length - 1) {
  if (start >= end) return; // Base Case

  const borderIndex = partition(arr, start, end); // ๋ฐฐ์—ด์„ ๋‚˜๋ˆ„๋Š” ๊ฒฝ๊ณ„ ์ธ๋ฑ์Šค
  quickSort(arr, start, borderIndex - 1); // borderIndex ์™ผ์ชฝ ์š”์†Œ
  quickSort(arr, borderIndex, end); // borderIndex ์˜ค๋ฅธ์ชฝ ์š”์†Œ

  return arr;
}

function partition(arr, start, end) {
  const pivot = arr[Math.floor((start + end) / 2)]; // ๊ฐ€์šด๋ฐ ์š”์†Œ๋ฅผ pivot์œผ๋กœ ์„ค์ •

  let i = start; // ์™ผ์ชฝ ํฌ์ธํ„ฐ
  let j = end; // ์˜ค๋ฅธ์ชฝ ํฌ์ธํ„ฐ

  // i/j ํฌ์ธํ„ฐ๊ฐ€ ๊ต์ฐจํ•  ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณต(๊ต์ฐจ ์ „์ด๋ผ๋ฉด pivot ์™ผ์ชฝ์— ๋” ํฐ ๊ฐ’์ด ๋‚จ์•„ ์žˆ๋Š” ์ƒํƒœ)
  while (i <= j) {
    while (arr[i] < pivot) i++; // ๋ฐฐ์—ด ์™ผ์ชฝ๋ถ€ํ„ฐ pivot ๊ฐ’ ๋ณด๋‹ค ํฐ ์š”์†Œ์˜ ์ธ๋ฑ์Šค ๊ฒ€์ƒ‰
    while (arr[j] > pivot) j--; // ๋ฐฐ์—ด ์˜ค๋ฅธ์ชฝ๋ถ€ํ„ฐ pivot ๊ฐ’ ๋ณด๋‹ค ์ž‘์€ ์š”์†Œ์˜ ์ธ๋ฑ์Šค ๊ฒ€์ƒ‰

    // i/j ํฌ์ธํ„ฐ๊ฐ€ ๊ต์ฐจ์ „์ด๋ผ๋ฉด
    if (i <= j) {
      // i < j : i ์ธ๋ฑ์Šค ์š”์†Œ๊ฐ€ j ์ธ๋ฑ์Šค ์š”์†Œ๋ณด๋‹ค ๋ณด๋‹ค ํฐ ๊ฐ’์ด๋ฏ€๋กœ swap ํ›„ ์ธ๋ฑ์Šค ์ด๋™
      // i = j : ์ด๋ฏธ ๊ต์ฐจ ํ–ˆ์„๋•Œ๋„ ๋‹ค์Œ ๊ฒฝ๊ณ„ ์ธ๋ฑ์Šค๋ฅผ ์œ„ํ•ด i/j swap ํ›„ ์ธ๋ฑ์Šค ์ด๋™
      swap(arr, i, j);
      i++; // ๋‹ค์Œ ๊ฒ€์ƒ‰์„ ์œ„ํ•ด i + 1
      j--; // ๋‹ค์Œ ๊ฒ€์ƒ‰์„ ์œ„ํ•ด i - 1
    }
  }

  return i; // ๊ต์ฐจ ํ›„์˜ i ์ธ๋ฑ์Šค๋ฅผ ๋‹ค์Œ ๊ฒฝ๊ณ„ ์ธ๋ฑ์Šค๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋ฆฌํ„ด
}

 

๋กœ๊ทธ(Logarithm) ์ฐธ๊ณ  ๋‚ด์šฉ

์‹œ๊ฐ„ ๋ณต์žก๋„์—์„œ ๋กœ๊ทธ๋Š” ๋ฐ‘(base)์„ ํ‘œ๊ธฐํ•˜์ง€ ์•Š์ง€๋งŒ, ๋ฐ‘์ด 2์ธ ๋กœ๊ทธ๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค(logโ‚‚N).

 

  • ๋กœ๊ทธ๋Š” ์ง€์ˆ˜(exponent)์˜ ์ •๋ฐ˜๋Œ€ ๊ฐœ๋…. 2๋ฅผ ๋ช‡ ๋ฒˆ ๊ฑฐ๋“ญ์ œ๊ณฑํ•ด์•ผ 32๊ฐ€ ๋‚˜์˜ค๋Š”์ง€ ๊ณ„์‚ฐํ•˜๋Š”๊ฒŒ ์ง€์ˆ˜, 32๋Š” 2๋ฅผ ๋ช‡ ๋ฒˆ ๋‚˜๋ˆ ์•ผ 1์ด ๋‚˜์˜ค๋Š”์ง€ ๊ณ„์‚ฐํ•˜๋Š”๊ฒŒ ๋กœ๊ทธ. ์ฐธ๊ณ ๋กœ ๋กœ๊ทธ๋Š” ์ง€์ˆ˜ ๋ฐฉ์ •์‹์œผ๋กœ ๋ฐ”๊ฟ”์„œ ๊ณ„์‚ฐํ•˜๋ฉด ํŽธํ•จ(logโ‚(b)a๋ฅผ ๋ช‡ ๋ฒˆ ์ œ๊ณฑํ•ด์•ผ b๊ฐ€ ๋‚˜์˜ฌ์ง€ ๊ณ„์‚ฐํ•ด๋ณธ๋‹ค).
    • ์ง€์ˆ˜ : 2โฟ = 32 → 32๋Š” 2๋ฅผ 5๋ฒˆ ๊ฑฐ๋“ญ์ œ๊ณฑํ•ด์•ผ ๋‚˜์˜ค๋ฏ€๋กœ n = 5
    • ๋กœ๊ทธ : logโ‚‚(32) = n → 32๋Š” 2๋ฅผ 5๋ฒˆ ๋‚˜๋ˆ ์•ผ 1์ด ๋‚˜์˜ค๋ฏ€๋กœ n = 5
  • ์ฆ‰, O(logN)์€ ๋ฐ์ดํ„ฐ ์›์†Œ๊ฐ€ N๊ฐœ ์žˆ์„ ๋•Œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด logโ‚‚N ๋‹จ๊ณ„๊ฐ€ ๊ฑธ๋ฆฐ๋‹ค๋Š” ์˜๋ฏธ. ์š”์†Œ๊ฐ€ 8๊ฐœ๋ผ๋ฉด logโ‚‚8 = 3 ์ด๋ฏ€๋กœ O(logN) ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ 3๋‹จ๊ณ„๊ฐ€ ํ•„์š”ํ•œ ๊ฒƒ์œผ๋กœ ํ•ด์„ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

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


โถ Worst Case(์ด๋ฏธ ์ •๋ ฌ๋œ ๋ฐฐ์—ด์— ์ตœ์†Œ or ์ตœ๋Œ€๊ฐ’์„ ํ”ผ๋ฒ—์œผ๋กœ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ) : O(n²)

 

์ด๋ฏธ ์ •๋ ฌ๋œ ๋ฐฐ์—ด์— ์ตœ์†Œ ํ˜น์€ ์ตœ๋Œ€๊ฐ’์„ ํ”ผ๋ฒ—์œผ๋กœ ์ง€์ •ํ•˜๋ฉด, ๋ฐฐ์—ด์„ ๋‚˜๋ˆ„๋Š” ๊ฒฝ๊ณ„ ์ธ๋ฑ์Šค๊ฐ€ ํ•ญ์ƒ ์ฒซ๋ฒˆ์งธ ํ˜น์€ ๋งˆ์ง€๋ง‰์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฆฌ์ŠคํŠธ์˜ ๋ถˆ๊ท ํ˜• ๋ถ„ํ• ๋กœ ์ธํ•ด n๋ฒˆ ๋งŒํผ ์ˆœํ™˜ํ˜ธ์ถœํ•œ๋‹ค. ๊ฐ ์ˆœํ™˜ํ˜ธ์ถœ๋งˆ๋‹ค ๋ฆฌ์ŠคํŠธ์˜ ๋ชจ๋“  ์š”์†Œ๋ฅผ ๋น„๊ตํ•˜๋ฏ€๋กœ O(n²) ์‹œ๊ฐ„ ๋ณต์žก๋„๋ฅผ ๊ฐ–๋Š”๋‹ค.

 

์žฌ๊ท€ ํ˜ธ์ถœ์˜ ๊นŠ์ด๊ฐ€ n๊ณผ ๋™์ผํ•œ ์ตœ์•…์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„ โ˜ ์ด๋ฏธ์ง€ ์ถœ์ฒ˜ rhtn

โท Best / Average Case(์ •๋ ฌ์ด ์•ˆ๋์„ ๋•Œ) : O(nlogโ‚‚n) 

 

์ˆœํ™˜ ํ˜ธ์ถœ์˜ ๊นŠ์ด (์žฌ๊ท€ ํ˜ธ์ถœ์˜ ๊นŠ์ด)


๋”๋ณด๊ธฐ
์ด๋ฏธ์ง€ ๋ฐ ์„ค๋ช… ์ถœ์ฒ˜ - gmlwjd9405
  • ๋ ˆ์ฝ”๋“œ์˜ ๊ฐœ์ˆ˜ n์ด 2์˜ ๊ฑฐ๋“ญ์ œ๊ณฑ n = 2^k ์ด๋ผ๊ณ  ๊ฐ€์ •ํ–ˆ์„ ๋•Œ
  • n = 2^3์€  2^3, 2^2, 2^1, 2^0 ์ˆœ์œผ๋กœ ์ค„์–ด๋“ค์–ด ์ˆœํ™˜ ํ˜ธ์ถœ์˜ ๊นŠ์ด๊ฐ€ 3์ž„์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค
  • ์œ„๋ฅผ ํ† ๋Œ€๋กœ n = 2^k์„ ์ผ๋ฐ˜ํ™”ํ•˜๋ฉด k(k = logโ‚‚n)์ž„์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค → k = logโ‚‚n

$k = logโ‚‚n$ (๋ฐ์ดํ„ฐ ๊ธธ์ด n์ด 8์ด๋ผ๊ณ  ๊ฐ€์ •, 8์€ 2๋ฅผ 3๋ฒˆ ์ œ๊ณฑํ•ด์•ผ ๋‚˜์˜ค๋ฏ€๋กœ ์žฌ๊ท€ ํ˜ธ์ถœ์˜ ๊นŠ์ด k๋Š” 3)

 

๋ณ‘ํ•ฉ ์ •๋ ฌ ๋ฐ ํ€ต ์ •๋ ฌ์€ ๋ฐ์ดํ„ฐ ๊ธธ์ด๊ฐ€ 1์ด ๋ ๋•Œ๊นŒ์ง€ ์ ˆ๋ฐ˜์”ฉ ๋ถ„ํ• ํ•œ๋‹ค. ๋ฐ์ดํ„ฐ ๊ธธ์ด๊ฐ€ 8์ด๋ผ๋ฉด 4(8/2) → 2(4/2) → 1(2/2) ๋ถ„ํ•  ๊ณผ์ •์„ ๊ฑฐ์น˜๋ฏ€๋กœ ๊นŠ์ด๋Š” 3์ด ๋œ๋‹ค. [21, 10, 12, 20, 25, 13, 15, 22] ๋ฐฐ์—ด์„ ์˜ˆ๋ฅผ ๋“ค์–ด๋ณด๋ฉด…

 

  • 1 depth : 8 / 2 = 4n / 2 ํฌ๊ธฐ์˜ ๋ถ€๋ถ„ ๋ฐฐ์—ด 1์Œ ๋น„๊ต (๋ถ€๋ถ„ ๋ฐฐ์—ด ๊ฐœ์ˆ˜ 2๊ฐœ)
    • ( [21, 10, 12, 20] — L
    • [25, 13, 15, 22] )โ‘  — R
  • 2 depth : 4 / 2 = 2n / 4 ํฌ๊ธฐ์˜ ๋ถ€๋ถ„ ๋ฐฐ์—ด 2์Œ ๋น„๊ต (๋ถ€๋ถ„ ๋ฐฐ์—ด ๊ฐœ์ˆ˜ 4๊ฐœ)
    • ( [21, 10] [12, 20] )โ‘  — L
    • ( [25, 13] [15, 22] )โ‘ก — R
  • 3 depth : 2 / 2 = 1n / 8 ํฌ๊ธฐ์˜ ๋ถ€๋ถ„ ๋ฐฐ์—ด 4์Œ ๋น„๊ต (๋ถ€๋ถ„ ๋ฐฐ์—ด ๊ฐœ์ˆ˜ 8๊ฐœ)
    • ( [21] [10] )โ‘  ( [12] [20] )โ‘ก — L
    • ( [25] [13] )โ‘ข ( [15] [22] )โ‘ฃ — R

 

์ˆœํ™˜ ํ˜ธ์ถœ ๋‹จ๊ณ„์˜ ๋น„๊ต ์—ฐ์‚ฐ

๊ฐ ์ˆœํ™˜(์žฌ๊ท€) ํ˜ธ์ถœ ๋‹จ๊ณ„๋งˆ๋‹ค ๋ฆฌ์ŠคํŠธ์˜ ๋ชจ๋“  ์š”์†Œ๋ฅผ ํ”ผ๋ฒ— ์š”์†Œ์™€ ๋น„๊ตํ•˜๋ฏ€๋กœ ์ด n๋ฒˆ์˜ ๋น„๊ต๊ฐ€ ์ด๋ค„์ง„๋‹ค.

๊ฐ ์ˆœํ™˜ ํ˜ธ์ถœ ๋‹จ๊ณ„๋งˆ๋‹ค ์ตœ๋Œ€ n๋ฒˆ์˜ ๋น„๊ต ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๋ฏ€๋กœ ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š”…
๊ฐ ์ˆœํ™˜ ํ˜ธ์ถœ ๋‹จ๊ณ„์˜ ๋น„๊ต ์—ฐ์‚ฐ(n) × ์ˆœํ™˜ ํ˜ธ์ถœ ๊นŠ์ด(logโ‚‚n) = nlogโ‚‚n
๋ฐ์ดํ„ฐ ๊ธธ์ด๊ฐ€ 8์ด๋ผ๋ฉด ์ตœ๋Œ€ 24๋ฒˆ์˜ ์ž‘์—… ์ˆ˜ํ–‰

 

์žฅ๋‹จ์ 


Stable ์ •๋ ฌ : ์ค‘๋ณต ๋ฐ์ดํ„ฐ๋Š” ์ˆœ์„œ๋ฅผ ๋ฐ”๊พธ์ง€ ์•Š๋Š” ๋ฐฉ์‹(Unstable ์ •๋ ฌ์€ ์ค‘๋ณต ๋ฐ์ดํ„ฐ๋„ ์ˆœ์„œ ๋ฐ”๊ฟˆ)
In-place ์ •๋ ฌ : ์ƒˆ๋กœ์šด ๋ฐฐ์—ด ์ƒ์„ฑ ์—†์ด ๊ธฐ์กด ๋ฐฐ์—ด๋งŒ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜, ์ถฉ๋ถ„ํžˆ ๋ฌด์‹œํ• ๋งŒํ•œ ์ €์žฅ ๊ณต๊ฐ„๋งŒ ๋” ์‚ฌ์šฉํ•˜๋Š” ์ •๋ ฌ ๋ฐฉ์‹(Not In-place ์ •๋ ฌ์€ ์š”์†Œ ๊ฐœ์ˆ˜์— ๋น„๋ก€ํ•˜๋Š” ์ €์žฅ๊ณต๊ฐ„์„ ๋” ์‚ฌ์šฉํ•จ)

 

  1. ์žฅ์  (In-place ์ •๋ ฌ ๋ฐฉ์‹ ๊ธฐ์ค€)
    • ๋น ๋ฅธ ์ •๋ ฌ ์†๋„ (O(nlogโ‚‚n) ์‹œ๊ฐ„ ๋ณต์žก๋„๋ฅผ ๊ฐ–๋Š” ๋‹ค๋ฅธ ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ค‘์—์„œ ๊ฐ€์žฅ ๋น ๋ฆ„)
    • ์ถ”๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ ์•ˆํ•จ
  2. ๋‹จ์  (In-place ์ •๋ ฌ ๋ฐฉ์‹ ๊ธฐ์ค€)
    • ์ •๋ ฌ๋œ ๋ฆฌ์ŠคํŠธ์— ์ตœ์†Œ or ์ตœ๋Œ€๊ฐ’์„ ํ”ผ๋ฒ—์œผ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ์ˆ˜ํ–‰์‹œ๊ฐ„ ๋” ๊ธธ์–ด์ง
    • Unstable ์ •๋ ฌ ๋ฐฉ์‹

 

๋ ˆํผ๋Ÿฐ์Šค


 


๊ธ€ ์ˆ˜์ •์‚ฌํ•ญ์€ ๋…ธ์…˜ ํŽ˜์ด์ง€์— ๊ฐ€์žฅ ๋น ๋ฅด๊ฒŒ ๋ฐ˜์˜๋ฉ๋‹ˆ๋‹ค. ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•ด ์ฃผ์„ธ์š”
๋ฐ˜์‘ํ˜•