๐Ÿ’ก ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ๋Š” ์ด๋ฆ„์—์„œ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด, ์‚ฝ์ž…์ด๋‚˜ ์‚ญ์ œ๋ณด๋‹ค๋Š” ํƒ์ƒ‰์— ์ฃผ ๋ชฉ์ ์„ ๋‘” ์ž๋ฃŒ๊ตฌ์กฐ์ด๋‹ค.

 

Search Tree

ํƒ์ƒ‰ ํŠธ๋ฆฌ


  • skip lists์™€ hash table๋“ค๊ณผ ๊ฐ™๊ฑฐ๋‚˜ ๊ทธ ์ด์ƒ์˜ ์„ฑ๋Šฅ์„ ๊ฐ€์ง
  • ์‚ฌ์ „์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ์— ์ด์ƒ์ ์ธ ๊ตฌ์กฐ
  • ์ˆœ์ฐจ์  ๋˜๋Š” ๋“ฑ๊ธ‰๋ณ„ ๋ฐ์ดํ„ฐ ์ ‘๊ทผ์— ์ด์ƒ์ 
๐Ÿ’ก ๋นˆ์ถœ! ์ด์ง„ ํŠธ๋ฆฌ์™€ ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ์˜ ์ฐจ์ด์ 

     - ์ด์ง„ ํŠธ๋ฆฌ : ๋…ธ๋“œ์˜ ์ตœ๋Œ€ Branch๊ฐ€ 2์ธ ํŠธ๋ฆฌ
     - ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ : ์ด์ง„ ํŠธ๋ฆฌ์— ์ถ”๊ฐ€์ ์ธ ์กฐ๊ฑด์ด ์žˆ๋Š” ํŠธ๋ฆฌ
           ⇒ ์กฐ๊ฑด : ์™ผ์ชฝ ๋…ธ๋“œ๋Š” ํ•ด๋‹น ๋…ธ๋“œ๋ณด๋‹ค ์ž‘์€ ๊ฐ’, ์˜ค๋ฅธ์ชฝ ๋…ธ๋“œ๋Š” ํ•ด๋‹น ๋…ธ๋“œ๋ณด๋‹ค ํฐ ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์žˆ์Œ.

 

 

Binary Search Tree

์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ


์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ๋Š” ํŠธ๋ฆฌ๊ฐ€ ๋น„์–ด์žˆ์ง€ ์•Š์€ ๊ฒฝ์šฐ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์†์„ฑ์„ ๋งŒ์กฑํ•œ๋‹ค.

  • ๋ชจ๋“  ๋…ธ๋“œ x์— ๋Œ€ํ•˜์—ฌ,์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ์˜ ๋ชจ๋“  key๊ฐ’์€ ๋…ธ๋“œ x์˜ key๊ฐ’๋ณด๋‹ค ํฌ๋‹ค.
  • ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ์˜ ๋ชจ๋“  key๊ฐ’์€ ๋…ธ๋“œ x์˜ key๊ฐ’๋ณด๋‹ค ์ž‘๋‹ค.
  • ๋ชจ๋“  ๋…ธ๋“œ๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ์œ ์ผํ•œ key๊ฐ’์„ ๊ฐ€์ง
  • ์™ผ์ชฝ ์„œ๋ธŒ ํŠธ๋ฆฌ์™€ ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒ ํŠธ๋ฆฌ๋„ ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ์ž„
  • ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ๋ฅผ ์ค‘์œ„ ์ˆœํšŒํ•˜๋ฉด ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌ๋œ ๊ฐ’์„ ์–ป์„ ์ˆ˜ ์žˆ์Œ

 

 

๊ตฌํ˜„


์ž‘์—…์ด ์ˆ˜ํ–‰๋จ์— ๋”ฐ๋ผ ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ์˜ ๋ชจ์–‘๊ณผ ์š”์†Œ๋“ค์˜ ์ˆ˜๊ฐ€ ๋ณ€ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ผ๋ฐ˜์ ์œผ๋กœ linked representation์„ ์‚ฌ์šฉํ•˜์—ฌ ํ‘œํ˜„๋œ๋‹ค.

Python ๊ตฌํ˜„ ํด๋ž˜์Šค ์ •์˜ ๋ฐ ์ดˆ๊ธฐํ™”

class Node(object):                       # ๋จผ์ € Node ํด๋ž˜์Šค๋ฅผ ์ •์˜
    def __init__(self, data):
        self.data = data
        self.left = self.right = None     # ์ดˆ๊ธฐํ™”ํ•  ๋•Œ๋Š” ๋ฐ์ดํ„ฐ ๊ฐ’๋งŒ ์ฃผ์–ด์ง€๊ณ  ์ขŒ์šฐ ๋…ธ๋“œ๋Š” ๋น„์–ด์žˆ์Œ

class BinarySearchTree(object):
    def __init__(self):
        self.root = None                # ์ฒ˜์Œ์—๋Š” ๋น„์–ด ์žˆ๋Š” ํŠธ๋ฆฌ๋กœ ์ดˆ๊ธฐํ™”

 

 

ํƒ์ƒ‰


๋ฃจํŠธ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๋ฉฐ, key๊ฐ€ ๋ฃจํŠธ๋ณด๋‹ค ์ž‘์œผ๋ฉด ์™ผ์ชฝ ํ•˜์œ„ ํŠธ๋ฆฌ๊ฐ€ ํƒ์ƒ‰๋˜๊ณ  key๊ฐ€ ๋ฃจํŠธ๋ณด๋‹ค ํฌ๋ฉด ์˜ค๋ฅธ์ชฝ ํ•˜์œ„ ํŠธ๋ฆฌ๊ฐ€ ํƒ์ƒ‰๋œ๋‹ค. key๊ฐ€ ๋ฃจํŠธ์™€ ๊ฐ™์œผ๋ฉด ๊ฒ€์ƒ‰์ด ์„ฑ๊ณต์ ์œผ๋กœ ์ข…๋ฃŒ๋œ๋‹ค.

  • ๋ฃจํŠธ๊ฐ€ NULL์ด๋ฉด ํƒ์ƒ‰ ํŠธ๋ฆฌ๊ฐ€ ํŠธ๋ฆฌ๊ฐ€ ๋น„์–ด ์žˆ์–ด ํƒ์ƒ‰ ์‹คํŒจ
  • ์‹œ๊ฐ„ ๋ณต์žก๋„ O(height)

Python ๊ตฌํ˜„ : find() Method ์žฌ๊ท€์™€ ๊ฐ’์˜ ๋Œ€์†Œ๊ด€๊ณ„ ๋น„๊ต๋ฅผ ํ†ตํ•ด ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

class BinarySearchTree(object):

  ...
  def find(self, key):
      return self._find_value(self.root, key)
  def _find_value(self, root, key):
      if root is None or root.data == key:
          return root is not None
      elif key < root.data:
          return self._find_value(root.left, key)
      else:
          return self._find_value(root.right, key)

 

 

์‚ฝ์ž…


  • ์ด์ง„ ๊ฒ€์ƒ‰ ํŠธ๋ฆฌ์— ์ƒˆ ์š”์†Œ e๋ฅผ ์‚ฝ์ž…ํ•˜๋ ค๋ฉด ๋จผ์ € ํŠธ๋ฆฌ์—์„œ ํƒ์ƒ‰์„ ์ˆ˜ํ–‰ํ•˜์—ฌ key๊ฐ€ ์ด๋ฏธ ์กด์žฌํ•˜์ง€ ์•Š๋Š”์ง€ ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค.
  • ํƒ์ƒ‰์ด ์„ฑ๊ณตํ•˜๋ฉด ์‚ฝ์ž…ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ํƒ์ƒ‰์— ์‹คํŒจํ•˜๋ฉด ์š”์†Œ๊ฐ€ ๊ฒ€์ƒ‰์ด ์ข…๋ฃŒ๋œ ์ง€์ ์— ์‚ฝ์ž…๋œ๋‹ค.
๐Ÿ’ก ์™œ ๊ทธ ์ง€์ ์— ์‚ฝ์ž…๋˜๋Š”๊ฐ€?
ํƒ์ƒ‰์˜ ์›๋ฆฌ๋ฅผ ์ดํ•ดํ–ˆ์œผ๋ฉด ์‰ฝ๋‹ค. ํƒ์ƒ‰ ์ค‘ ๋ฃจํŠธ๊ฐ€ NULL์œผ๋กœ ํŠธ๋ฆฌ๊ฐ€ ๋น„์–ด์žˆ๋Š” ๊ฒฝ์šฐ ํƒ์ƒ‰์— ์‹คํŒจํ•˜๊ธฐ ๋•Œ๋ฌธ
  • ์‹œ๊ฐ„ ๋ณต์žก๋„ O(height)

 

Python ๊ตฌํ˜„ ์˜ˆ์‹œ : Insert Method

๐Ÿ‘‰๐Ÿป insert 7

์žฌ๊ท€๋ฅผ ์ด์šฉํ•ด์„œ ๊ตฌํ˜„ํ•˜๋ฉด ๊ฐ„๋‹จํ•˜๋‹ค. ์ƒˆ๋กœ ์ถ”๊ฐ€ํ•  ์›์†Œ์˜ ๊ฐ’์„ ํ˜„์žฌ ๋…ธ๋“œ์˜ ๊ฐ’๊ณผ ๋น„๊ตํ•˜์—ฌ ์™ผ์ชฝ/์˜ค๋ฅธ์ชฝ ์ค‘ ์•Œ๋งž์€ ์œ„์น˜๋กœ ๋…ธ๋“œ๋ฅผ ์˜ฎ๊ฒจ๊ฐ€๋ฉด์„œ ์‚ฝ์ž… ์œ„์น˜๋ฅผ ํ™•์ธํ•œ๋‹ค.

  class BinarySearchTree(object):
      ...
      def insert(self, data):
          self.root = self._insert_value(self.root, data)
          return self.root is not None
      def _insert_value(self, node, data):
          if node is None:
              node = Node(data)
          else:
              if data <= node.data:
                  node.left = self._insert_value(node.left, data)
              else:
                  node.right = self._insert_value(node.right, data)
          return node

 

 

 

์‚ญ์ œ


์š”์†Œ์˜ ์‚ญ์ œ๋Š” ์„ธ ๊ฐ€์ง€ ๊ฒฝ์šฐ๋กœ ๋‚˜๋ˆ„์–ด ์ƒ๊ฐํ•ด๋ณผ ์ˆ˜ ์žˆ๋‹ค.

case 1 : ์š”์†Œ๊ฐ€ leaf์— ์žˆ๋‹ค.

๐Ÿ‘‰๐Ÿป Ex) delete key=7

Untitled 2

 

case 2 : ์š”์†Œ๊ฐ€ ์ฐจ์ˆ˜ 1์˜ ๋…ธ๋“œ์— ์žˆ๋‹ค (์ฆ‰, ๋น„์–ด ์žˆ์ง€ ์•Š์€ ์„œ๋ธŒํŠธ๋ฆฌ๊ฐ€ ํ•˜๋‚˜ ์กด์žฌ).

๐Ÿ‘‰๐Ÿป delete key=40

Untitled 3
 
๐Ÿ‘‰๐Ÿป delete key=15
Untitled 4

 

case 3 : ์š”์†Œ๊ฐ€ ์ฐจ์ˆ˜ 2์˜ ๋…ธ๋“œ์— ์žˆ๋‹ค (์ฆ‰, ๋น„์–ด ์žˆ์ง€ ์•Š์€ ๋‘ ๊ฐœ์˜ ์„œ๋ธŒํŠธ๋ฆฌ๊ฐ€ ์กด์žฌ).

๐Ÿ‘‰๐Ÿป Ex 1) delete key=10s

Untitled 5
โ–ฒ step 1
 
Untitled 6
 
โ–ฒ step 2. ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ์—์„œ ๊ฐ€์žฅ ํฐ key๋กœ ๋Œ€์ฒด
(๋˜๋Š” ์˜ค๋ฅธ์ชฝ ํ•˜์œ„ ํŠธ๋ฆฌ์—์„œ ๊ฐ€์žฅ ์ž‘์€ key๋กœ ๋Œ€์ฒด)
 
Untitled 7
:--:
โ–ฒ step 3. ๊ฐ€์žฅ ํฐ key๋Š” leaf ๋˜๋Š” ์ฐจ์ˆ˜ 1์ธ ๋…ธ๋“œ์— ์žˆ์–ด์•ผ ํ•œ๋‹ค.

 

๐Ÿ‘‰๐Ÿป Ex 2) delete key=20

Untitled 8
โ–ฒ ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ์˜ ๊ฐ€์žฅ ํฐ key๊ฐ’์œผ๋กœ ๋Œ€์ฒดํ•œ๋‹ค.

๐Ÿ’ฌ ์™ผ์ชฝ ์„œ๋ธŒ ํŠธ๋ฆฌ์—์„œ key๊ฐ€ ๊ฐ€์žฅ ํฐ ๋…ธ๋“œ(+ ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒ ํŠธ๋ฆฌ์—์„œ key๊ฐ€ ๊ฐ€์žฅ ์ž‘์€ ๋…ธ๋“œ)๋Š” 0 ๋˜๋Š” ๋น„์–ด ์žˆ์ง€ ์•Š์€ ์„œ๋ธŒ ํŠธ๋ฆฌ๊ฐ€ ํ•˜๋‚˜ ์žˆ๋Š” ๋…ธ๋“œ์— ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

๐Ÿ’ก ๋…ธ๋“œ์˜ ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ์—์„œ key๊ฐ€ ๊ฐ€์žฅ ํฐ ๋…ธ๋“œ๋ฅผ ์ฐพ๋Š” ๋ฐฉ๋ฒ•
    ์„œ๋ธŒ ํŠธ๋ฆฌ์˜ ๋ฃจํŠธ๋กœ ์ด๋™ํ•œ ๋‹ค์Œ ์˜ค๋ฅธ์ชฝ ์ž์‹์˜ ํฌ์ธํ„ฐ๊ฐ€ NULL์ธ ๋…ธ๋“œ์— ๋„๋‹ฌํ•  ๋•Œ๊นŒ์ง€ ๊ณ„์† ์˜ค๋ฅธ์ชฝ ์ž์‹
    ํฌ์ธํ„ฐ๋ฅผ ๋”ฐ๋ผ๊ฐ„๋‹ค.
๐Ÿ’ก ๋…ธ๋“œ์˜ ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ์—์„œ key๊ฐ€ ๊ฐ€์žฅ ์ž‘์€ ๋…ธ๋“œ๋ฅผ ์ฐพ๋Š” ๋ฐฉ๋ฒ•
    ์„œ๋ธŒ ํŠธ๋ฆฌ์˜ ๋ฃจํŠธ๋กœ ์ด๋™ํ•œ ๋‹ค์Œ ์™ผ์ชฝ ์ž์‹์˜ ํฌ์ธํ„ฐ๊ฐ€ NULL์ธ ๋…ธ๋“œ์— ๋„๋‹ฌํ•  ๋•Œ๊นŒ์ง€ ๊ณ„์† ์™ผ์ชฝ ์ž์‹
    ํฌ์ธํ„ฐ๋ฅผ ๋”ฐ๋ผ๊ฐ„๋‹ค.

  • ์‹œ๊ฐ„๋ณต์žก๋„ : O(height)

 

Python ๊ตฌํ˜„ ์˜ˆ์‹œ : delete Method

  class BinarySearchTree(object):
      ...
      def delete(self, key):
          self.root, deleted = self._delete_value(self.root, key)
          return deleted
      def _delete_value(self, node, key):
          if node is None:
              return node, False
          deleted = False
          if key == node.data:
              deleted = True
              if node.left and node.right:
                                  # replace the node to the leftmost of node.right
                  parent, child = node, node.right
                  while child.left is not None:
                      parent, child = child, child.left
                  child.left = node.left
                  if parent != node:
                      parent.left = child.right
                      child.right = node.right
                  node = child
              elif node.left or node.right:
                  node = node.left or node.right
              else:
                  node = None
          elif key < node.data:
              node.left, deleted = self._delete_value(node.left, key)
          else:
              node.right, deleted = self._delete_value(node.right, key)
          return node, deleted

 

 

 

 

Binary Search Tree์˜ ์‹œ๊ฐ„๋ณต์žก๋„


  • ์ด์ง„ ํŠธ๋ฆฌ์˜ ์ขŒ์šฐ ๊ท ํ˜•์ด ๋งž๋Š”๋‹ค๋ฉด ํƒ์ƒ‰, ์‚ฝ์ž…, ์‚ญ์ œ์˜ ์‹œ๊ฐ„๋ณต์žก๋„๊ฐ€ O(log n)
  • ๊ทธ๋Ÿฌ๋‚˜ ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ๋Š” ์ •๋ ฌ๋œ ๋ฐ์ดํ„ฐ์—๋Š” ์ทจ์•ฝํ•˜๋‹ค.⇒ ์ตœ์•…์˜ ๊ฒฝ์šฐ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ์‚ดํŽด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์–ด ์‹œ๊ฐ„๋ณต์žก๋„๊ฐ€ O(n)์ด ๋œ๋‹ค.
  • → ์˜ค๋ฆ„์ฐจ์ˆœ์ด๋“  ๋‚ด๋ฆผ์ฐจ์ˆœ์ด๋“  ์ •๋ ฌ๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ์ž…๋ ฅ๋˜๋ฉด ํŽธํ–ฅ ํŠธ๋ฆฌ(skewed tree)๊ฐ€ ์ƒ๊น€



 

 

Indexed Binary Search Trees


-

Untitled 9

  • ๊ฐ ๋…ธ๋“œ์—๋Š” ์ถ”๊ฐ€์ ์ธ ํ•„๋“œ ‘LeftSize’๋ผ๋Š” ๋ณ€์ˆ˜๊ฐ€ ์žˆ์Œ
  • ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ์˜ ๊ธฐ๋Šฅ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ˆœ์œ„(rank)๋ณ„ ๊ฒ€์ƒ‰ ๋ฐ ์‚ญ์ œ ์ž‘์—…์ด ๊ฐ€๋Šฅ
  • LeftSize : ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ์˜ ์›์†Œ ์ˆ˜

 

LeftSize์™€ Rank

  • ์š”์†Œ์˜ rank ์ฆ‰, ์ˆœ์œ„๋Š” ์˜ค๋ฆ„์ฐจ์ˆœ ์ˆœ์„œ์— ๋”ฐ๋ฅธ ์œ„์น˜๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.rank(2) = 0rank(20) = 7Untitled 10
  • rank(15) = 5
  • [2, 6, 7, 8, 10, 15, 18, 20, 25, 30, 35, 40]

  • x๋ฅผ ๋ฃจํŠธ๋…ธ๋“œ๋กœ ํ•˜๋Š” ์„œ๋ธŒํŠธ๋ฆฌ์˜ ์š”์†Œ์— ๋Œ€ํ•˜์—ฌ LeftSize(x) = rank(x)
  • indexed Binary Tree์˜ ํ™œ์šฉ
  • insert(index, element)

  • ์—ฌ๋Ÿฌ ๊ฐ€๋Šฅ์„ฑ์ด ์กด์žฌํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋ฃจํŠธ ๋…ธ๋“œ๋ถ€ํ„ฐ ์ƒˆ๋กœ์šด ๋…ธ๋“œ๊นŒ์ง€์˜ leftSize๋ฅผ ์—…๋ฐ์ดํŠธํ•ด์•ผ ํ•œ๋‹ค.
  • ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” O(height)



Binary Search Tree with Duplicates

์ค‘๋ณต์ด ์žˆ๋Š” ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ

์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ์˜ ๋ชจ๋“  ์š”์†Œ์— ๋ณ„๋„์˜ key๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋Š” ์š”๊ตฌ์‚ฌํ•ญ์„ ์ œ๊ฑฐํ•ด๋ณผ ์ˆ˜ ์žˆ๋‹ค.

For every node x,

all keys in the left subtree of x are smaller than that in x.
all keys in the right subtree of x are larger than that in x

  • “smaller” → "smaller or equal to"๋กœ,
  • "larger" → "larger or equal to"์œผ๋กœ ๋ฐ”๊พผ๋‹ค.

๊ทธ๋Ÿฌ๋ฉด ์ด์ง„ ๊ฒ€์ƒ‰ ํŠธ๋ฆฌ๊ฐ€ ์ค‘๋ณต ํ‚ค๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.



 

์ฐธ๊ณ ์ž๋ฃŒ

BELATED ARTICLES

more