Merge Sort

์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ •๋ ฌ๋œ ์ž๋ฃŒ์˜ ์ง‘ํ•ฉ์„ ๋ณ‘ํ•ฉํ•˜์—ฌ ํ•œ ๊ฐœ์˜ ์ •๋ ฌ๋œ ์ง‘ํ•ฉ์œผ๋กœ ๋งŒ๋“œ๋Š” ๋ฐฉ์‹

์—ฐ๊ฒฐ list์˜ ๊ฒฝ์šฐ ๊ฐ€์žฅ ํšจ์œจ์ ์ธ ๋ฐฉ์‹!

๋ถ„ํ•  ์ •๋ณต ์•Œ๊ณ ๋ฆฌ์ฆ˜ ํ™œ์šฉ

  • ์ž๋ฃŒ๋ฅผ ์ตœ์†Œ ๋‹จ์œ„์˜ ๋ฌธ์ œ๊นŒ์ง€ ๋‚˜๋ˆˆ ํ›„์— ์ฐจ๋ก€๋Œ€๋กœ ์ •๋ ฌํ•˜์—ฌ ์ตœ์ข… ๊ฒฐ๊ณผ๋ฅผ ์–ป์–ด๋ƒ„

    • top-down ๋ฐฉ์‹

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

  • O(n log n)

๋ณ‘ํ•ฉ ์ •๋ ฌ์˜ ๊ณผ์ •

  1. ๋ถ„ํ•  ๋‹จ๊ณ„

    • ์ „์ฒด ์ž๋ฃŒ ์ง‘ํ•ฉ์— ๋Œ€ํ•˜์—ฌ, ์ตœ์†Œ ํฌ๊ธฐ์˜ ๋ถ€๋ถ„์ง‘ํ•ฉ์ด ๋  ๋•Œ๊นŒ์ง€ ๋ถ„ํ•  ์ž‘์—…์„ ๊ณ„์†ํ•จ

  2. ๋ณ‘ํ•ฉ ๋‹จ๊ณ„

    • 2๊ฐœ์˜ ๋ถ€๋ถ„์ง‘ํ•ฉ์„ ์ •๋ ฌํ•˜๋ฉด์„œ ํ•˜๋‚˜์˜ ์ง‘ํ•ฉ์œผ๋กœ ๋ณ‘ํ•ฉ

๋ถ„ํ•  ๊ณผ์ •์˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜

def merge_sort(m):
    if len(m) <= 1: #size๊ฐ€ 0์ด๊ฑฐ๋‚˜ 1์ธ ๊ฒฝ์šฐ ๋ฐ”๋กœ return
        return m
    
    # 1. Divide ๋ถ€๋ถ„
    mid = len(m)//2
    left = m[:mid]
    right = m[mid:]
    
    #list์˜ ํฌ๊ธฐ๊ฐ€ 1์ด ๋  ๋•Œ๊นŒ์ง€ merge_sort ์žฌ๊ท€ ํ˜ธ์ถœ
    left = merge_sort(left)
    right = merge_sort(right)
    
    # 2. Conquer ๋ถ€๋ถ„: ๋ถ„ํ• ๋œ list๋“ค ๋ณ‘ํ•ฉ
    ruturn merge(left, right)

๋ณ‘ํ•ฉ ๊ณผ์ •์˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜

def merge(left, right):
    result = [] #๋‘ ๊ฐœ์˜ ๋ถ„ํ• ๋œ list๋ฅผ ๋ณ‘ํ•ฉํ•˜์—ฌ result๋ฅผ ๋งŒ๋“ฆ
    
    while len(left) > 0 and len(right) >0: #์–‘์ชฝ list์— ์›์†Œ๊ฐ€ ๋‚จ์•„์žˆ๋Š” ๊ฒฝ์šฐ
        #๋‘ sub list์˜ ์ฒซ ์›์†Œ๋“ค์„ ๋น„๊ตํ•˜์—ฌ ์ž‘์€ ๊ฒƒ๋ถ€ํ„ฐ result์— ์ถ”๊ฐ€ํ•จ
        if left[0] <= right[0]:
            result.append(left.pop(0))
        else:
            result.append(right.pop(0))
    if len(left) > 0: #์™ผ์ชฝ list์— ์›์†Œ๊ฐ€ ๋‚จ์•„์žˆ๋Š” ๊ฒฝ์šฐ
        result.extend(left)
    if len(right) > 0: #์˜ค๋ฅธ์ชฝ list์— ์›์†Œ๊ฐ€ ๋‚จ์•„์žˆ๋Š” ๊ฒฝ์šฐ
        result.extend(right)
    return result

Last updated