์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ(Linked List)

๋…ธ๋“œ(node)

  • ๋ฐ์ดํ„ฐ๋“ค์„ ๊ฐ–๊ณ  ์žˆ๋Š” ์š”์†Œ๋“ค์ด ์ฐธ์กฐ๋กœ ์ด์–ด์ ธ ์žˆ์Œ
  • ๋…ธ๋“œ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด๋Š” ๋ถ€๋ถ„๊ณผ ๋‹ค์Œ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ์ฐธ์กฐ๋กœ ๊ตฌ์„ฑ
  • ์ด๋ ‡๊ฒŒ ๋ฐ์ดํ„ฐ์™€ ๋ฐ์ดํ„ฐ๋ฅผ ์—ฐ๊ฒฐ(link) ํ•ด๋‘์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ(Linked List) ๋ผ๊ณ  ํ•จ

์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ(Linked List)

  • ํฌ์ธํ„ฐ๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ์ž๋ฃŒ ๊ตฌ์กฐ
  • ๋ฌผ๋ฆฌ์  ๊ตฌ์กฐ๊ฐ€ ์ˆœ์ฐจ์ ์ด์ง€ ์•Š์Œ
  • ํฌ์ธํ„ฐ๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋ฏ€๋กœ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์— ์ธ์ ‘ํ•ด ์žˆ์ง€๋Š” ์•Š์Œ
  • ์‚ฝ์ž…๊ณผ ์‚ญ์ œ๊ฐ€ ๋นˆ๋ฒˆํ•œ ๊ฒฝ์šฐ ์‚ฌ์šฉ

png

์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ(Linked List)์˜ ์ข…๋ฅ˜

    1. ๋‹จ์ˆœ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(Single Linked List)
  • ๋‹ค์Œ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ์ฐธ์กฐ ํ•˜๋‚˜๋งŒ ๊ฐ€์ง€๊ณ  ์žˆ์Œ
  1. ์ด์ค‘ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(Double Linked List)
    • ์•ž ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ์ฐธ์กฐ์™€ ๋’ค ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ์ฐธ์กฐ๋ฅผ ๋ชจ๋‘ ๊ฐ€์ง€๊ณ  ์žˆ์Œ

png

์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ์˜ ์‚ฝ์ž…, ์‚ญ์ œ, ํƒ์ƒ‰

  1. ์‚ฝ์ž…

    ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ

    • ์ƒˆ๋กœ์šด ๋…ธ๋“œ ์ƒ์„ฑ
    • ์•ž ๋…ธ๋“œ์˜ ๋งํฌ๋ฅผ ์ƒ์„ฑ๋œ ๋…ธ๋“œ๋กœ ํ•˜๊ณ , ์ƒ์„ฑ๋œ ๋…ธ๋“œ์˜ ๋งํฌ๋ฅผ ๋’ท ๋…ธ๋“œ๋กœ ํ•œ๋‹ค

    ๋ฐฐ์—ด

    • ๋ฐฐ์—ด์˜ ๋งˆ์ง€๋ง‰์— ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•˜๋Š” ๊ฒฝ์šฐ๋ฅผ ์ œ์™ธํ•˜๊ณ  O(n)์˜ ์„ฑ๋Šฅ์„ ๊ฐ€์ง
    • ๋Š๋ฆฐ ์‚ฝ์ž…/์‚ญ์ œ

    png

  2. ์‚ญ์ œ

    ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ

    • ์‚ญ์ œํ•  ๋…ธ๋“œ ์•ž ๋…ธ๋“œ์˜ ๋งํฌ๋ฅผ ๋’ท ๋…ธ๋“œ๋กœ ์—ฐ๊ฒฐ์‹œํ‚จ๋‹ค.

    ๋ฐฐ์—ด

    • ๋ฐฐ์—ด์˜ ๋งˆ์ง€๋ง‰์— ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•˜๋Š” ๊ฒฝ์šฐ๋ฅผ ์ œ์™ธํ•˜๊ณ  O(n)์˜ ์„ฑ๋Šฅ์„ ๊ฐ€์ง
    • ๋Š๋ฆฐ ์‚ฝ์ž…/์‚ญ์ œ

    png

  3. ํƒ์ƒ‰

    ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ

    • ๋ฆฌ์ŠคํŠธ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋๊นŒ์ง€ ํ•˜๋‚˜์”ฉ ๋ฐฉ๋ฌธํ•˜๋ฉด์„œ ํ•ด๋‹น ์š”์†Œ๋ฅผ ๋น„๊ตํ•˜์—ฌ ์ฐพ์Œ

    ๋ฐฐ์—ด

    • ๋‹จ ํ•œ๋ฒˆ์˜ ์—ฐ์‚ฐ์œผ๋กœ ํ•ด๋‹น ์ธ๋ฑ์Šค์˜ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผ ๊ฐ€๋Šฅ

๋”๋ฏธ ์ด์ค‘ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(dummy double linked list)

  • ๋ณดํ†ต ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ๋ผ ํ•˜๋ฉด dummy double linked list๋ฅผ ์˜๋ฏธ
  • ๋”๋ฏธ ๋…ธ๋“œ๋ฅผ ์‚ฌ์šฉ
    • ๋”๋ฏธ๋…ธ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ head ํ˜น์€ tail ์˜ ๋”๋ฏธ๋…ธ๋“œ๋ฅผ ๊ธฐ์ค€์œผ๋กœ โ€œ ๊ทธ ๋’ค(์•ž)๋กœ ๋ช‡ ๋ฒˆ ๊ฐ€์„œ ์‚ฝ์ž…, ๊ทธ ๋’ค(์•ž)๋กœ ๋ช‡ ๋ฒˆ ๊ฐ€์„œ ์‚ญ์ œโ€๋ผ๋Š” ํ•˜๋‚˜์˜ ๋กœ์ง์œผ๋กœ ๋™์ž‘์ด ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ผ๋ฐ˜ํ™” ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Œ
  • head, tail์ด ๊ฐ€๋ฆฌํ‚ค๋Š” ๋”๋ฏธ๋…ธ๋“œ์—๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋˜์–ด์žˆ์ง€ ์•Š์Œ

    png

๋…ธ๋“œ ๊ตฌํ˜„

  • data ์™€ ์ฐธ์กฐํ•  prev / next ์ƒ์„ฑ
class Node:
    def __init__(self, data=None):
        self.__data=data
        self.__prev=None
        self.__next=None


    # ์†Œ๋ฉธ์ž : ๊ฐ์ฒด๊ฐ€ ์‚ฌ๋ผ์ง€๊ธฐ ์ „ ๋ฐ˜๋“œ์‹œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.
    # ์‚ญ์ œ ์—ฐ์‚ฐ ๋•Œ ์‚ญ์ œ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด
    # ์ž‘์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค.
    def __del__(self):
        print("data of {} is deleted".format(self.data))

    @property
    def data(self):
        return self.__data
    
    @data.setter
    def data(self, data):
        self.__data=data
    
    @property
    def prev(self):
        return self.__prev

    @prev.setter
    def prev(self, p):
        self.__prev=p

    @property
    def next(self):
        return self.__next

    @next.setter
    def next(self, n):
        self.__next=n

png

class DoubleLinkedList:
    def __init__(self):
        #๋”๋ฏธ๋…ธ๋“œ
        self.head=Node()
        self.tail=Node()
        
        #์ดˆ๊ธฐํ™”
        #head, tail ์—ฐ๊ฒฐ
        self.head.next=self.tail
        self.tail.prev=self.head
        
        self.d_size=0

    def empty(self):
        if self.d_size==0:
            return True
        else:
            return False

    def size(self):
        return self.d_size

    def add_first(self, data):
        #์ƒˆ๋กœ์šด ๋…ธ๋“œ ๋งŒ๋“ฆ
        new_node=Node(data)
        
        #์ƒˆ๋กœ์šด ๋…ธ๋“œ๋ฅผ ๋”๋ฏธ๋…ธ๋“œ ๋‹ค์Œ์„ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ํ•จ
        new_node.next=self.head.next
        #prev๋Š” ๋ฆฌ์ŠคํŠธ์˜ ๋งจ ์•ž ๋”๋ฏธ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ํ•จ
        new_node.prev=self.head

        #์ฒซ๋ฒˆ์งธ ๋ฐ์ดํ„ฐ๋…ธ๋“œ์˜ prev๊ฐ€ ์ƒˆ๋กœ์šด ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋„๋ก
        self.head.next.prev=new_node
        #๋”๋ฏธ๋…ธ๋“œ์˜ next๋Š” ์ƒˆ๋กœ์šด ๋…ธ๋“œ ๊ฐ€๋ฆฌํ‚ค๋„๋ก(์ƒˆ๋กœ์šด ๋…ธ๋“œ ์‚ฝ์ž…)
        self.head.next=new_node

        # d_size ์ฆ๊ฐ€์‹œํ‚ด
        self.d_size+=1

    def add_last(self, data):
        new_node=Node(data)

        new_node.prev=self.tail.prev
        new_node.next=self.tail

        self.tail.prev.next=new_node
        self.tail.prev=new_node

        self.d_size+=1

    def insert_after(self, data, node):
        new_node=Node(data)

        new_node.next=node.next
        new_node.prev=node

        node.next.prev=new_node
        node.next=new_node

        self.d_size+=1

    def insert_before(self, data, node):
        new_node=Node(data)

        new_node.prev=node.prev
        new_node.next=node

        node.prev.next=new_node
        node.prev=new_node

        self.d_size+=1

    def search_forward(self, target):
        cur=self.head.next
        
        while cur is not self.tail:
            if cur.data==target:
                return cur
            cur=cur.next
        return None

    def search_backward(self, target):
        cur=self.tail.prev
        while cur is not self.head:
            if cur.data==target:
                return cur
            cur=cur.prev
        return None
        
    def delete_first(self):
        if self.empty():
            return
        self.head.next=self.head.next.next
        self.head.next.prev=self.head

        self.d_size-=1

    def delete_last(self):
        if self.empty():
            return
        self.tail.prev=self.tail.prev.prev
        self.tail.prev.next=self.tail

        self.d_size-=1

    def delete_node(self, node):
        node.prev.next=node.next
        node.next.prev=node.prev

        self.d_size-=1