연결 리스트

노드 : 각각의 소세지

저장할 데이터와 다음 노드로의 연결을 포함하고 있다.

  • 단순연결리스트 : 한방향으로 연결된것
  • 이중연결리스트 : 양방향
  • 원형연결리스트 : 가장뒤의 노드가 맨앞의노드에 연결되어 있다.

배열과의 차이점

배열: 인덱스를이용해 데이터에 접근할수있다.

연결리스트는 현재노드에서 연결된노드로만 접근할수있다. 인덱스가 없다.

연결리스트가 시작하는곳 head

class Node:
    def __init__(self, val):
        self.val = val
        self.next = None

    def __str__(self):
        return str(self.val)

print에서 출력할때 str으로 변환해서 출력하는데 객체같은경우는 불가능하기때문에 str메소드를 지정했다.

연결리스트 - 왜알아야 하는가?

면접문제에 나온다!

그냥 대놓고 연결리스트를 언급하고 문제가 나온다. 마치 배민문제처럼..

효율성

효율성이 되게 없어보이는데;

트리, Database등 더 고차원 구조의 기반이 된다.

시간복잡도

중간걸 삭제하고 앞에것을 뒤랑 연결한다.

어레이는 중간에 추가하거나 삭제를하면 나머지 전체를 옮겨줘야하기 때문에 시간복잡도가 쫌 문제인데 O(N) 연결리스트는 그렇지 않다.

연결리스트에서 노드 삭제하기

# 연결 리스트의 노드. 단일 연결 리스트의 경우입니다.
class Node:
    def __init__(self, val):
        self.val = val
        self.next = None

    def __str__(self):
        return str(self.val)

# 연결 리스트 클래스. head 와 tail을 가지고 있으며, 가장 뒤에 새로운 노드를 추가하는 addToEnd 함수가 있습니다.
class LinkedList:
    def __init__(self, head):
        self.head = head
        self.tail = head

    def addToEnd(self, node):
        self.tail.next = node
        self.tail = node

    def __str__(self):
        node = self.head
        toPrint = []
        while node:
            toPrint.append(str(node.val))
            node = node.next
        return "->".join(toPrint)

# 주어진 배열을 linkedlist로 변환해서 돌려줍니다. 실습 3-1을 참조하세요
def toLinkedList(lst):
    ll = LinkedList(Node(lst[0]))
    for i in range(1, len(lst)):
        ll.addToEnd(Node(lst[i]))

    return ll

####################################################################################################################################

def deleteNode(ll, valToDelete):
    if ll.head.val == valToDelete:
        ll.head = ll.head.next

    currNode = ll.head
    nextNode = currNode.next

    while nextNode:    
        if nextNode.val == valToDelete:
            currNode.next = nextNode.next #nextNode.next 는 nextNode와 같다.
            if ll.tail == nextNode: #그래서 tail인지 확인하고, nextNode의 바로전Node로 대체한다.
                ll.tail = currNode
            break

        #노드이동.            
        currNode = currNode.next  
        nextNode = currNode.next  

def main():
    nums = [2,8,19,37,4,5]
    ll = toLinkedList(nums)
    print(ll)
    deleteNode(ll, 19)
    print(ll) # 19를 삭제하였으므로, 2->8->37->4->5
    deleteNode(ll, 3)
    print(ll) # 3이 없으므로, 2->8->37->4->5

내가만든 연결리스트

#민우코드

class Node:
  def __init__(self, val):
    self.val = val
    self.next = None
    self.before = None

  def __str__(self):
    return str(self.val)

class LList:
  def __init__(self, head):
    self.head = head
    self.tail = head

  def addToEnd(self, node):
    #add이전에 마지막노드(tail)을 새로넣는 노드의 이전노드로 지정.
    node.before = self.tail
    self.tail.next = node
    self.tail = node


  def __str__(self):
    node = self.head
    toPrint = []
    while node:
      toPrint.append(str(node.val))
      node = node.next
    return "->".join(toPrint)

  def find(self, valToFind):
    node = self.head
    while node:
      if node.val == valToFind:
        return node
      else:
        if node.next == None:
          return None
        node = node.next


  def deleteNode(self, valToDelete):
    node = self.find(valToDelete)
    if node:
      if self.head == node:
        self.head = self.head.next
      elif self.tail == node:
        #tail의 바로전노드의 next 프로퍼티를 tail.next(None)으로 바꾼다.
        self.tail.before.next = self.tail.next
        #tail을 기존tail의 바로전 노드로 바꾼다.
        self.tail = self.tail.before
      else:
        node.before.next = node.next
        node.next.before = node.before

    else:
      return None




ll = LList(Node(3))
ll.addToEnd(Node(4))
ll.addToEnd(Node(8))
print(ll.tail.before)
print(ll)
print(ll.deleteNode(8))
print(ll)

기출문제

class Node():
  def __init__(self, val):
    self.val = val
    self.next = None

class LL():
  def __init__(self, node):
    self.root = node
    self.tail = node

  def addToEnd(self, node):
    if self.tail.val == self.root.val and self.root.next is None:
      self.root.next = node
    else:
      self.tail.next = node
      self.tail = node

def arrayToLL(array):
  ll = LL(Node(array[0]))

  while ll.tail.val is not -1:
    ll.addToEnd(Node(array[ll.tail.val]))

  return ll

arr = [1,4,-1,3,2]
ll = arrayToLL(arr)

print(ll.root.val)
print(ll.root.next.val)
print(ll.root.next.next.val)
print(ll.root.next.next.next.val)
# print(ll.root.next.next.next.next.val) #None

results matching ""

    No results matching ""