データ構造シナリオ、リンクリスト


整列



私はノタビリティで自分で描いたあまりかわいくない絵です...

特長

  • Pythonは、「リスト」という抽象データ型の典型的な例
  • を実装する.
  • 配列に格納された値は、順序を表す番号(インデックス)を有する.
  • を使用して同類データを効率的に管理

    インプリメンテーション

    mylist = [1, 2, 3, 4, 5]
    
    # 조회
    print(mylist[0]) # 1
    
    # 삽입
    mylist.append(6) # [1, 2, 3, 4, 5, 6] - 맨 뒤에 원소 삽입
    mylist.insert(3, 10) # [1, 2, 3, 10 , 4, 5, 6] - 특정 인덱스에 원소 삽입
    
    # 삭제
    del mylist[3] # [1, 2, 3, 4, 5, 6] - 인덱스로 삭제
    mylist.remove(6) # [1, 2, 3, 4, 5] - 값으로 삭제
    mylist.pop() # [1, 2, 3, 4] - 매개변수 입력 않을 시 맨 마지막 값(-1) 삭제

    ¥2,000の長所

  • 配列内の特定の値を問い合わせるときに便利です.
  • 欠点

  • 資料の挿入/削除が面倒です.
  • 接続リスト(リンクリスト)せつぞくりすと(りんくりすと)



    特長


    別の例
  • は、Pythonにおいて「リスト」の抽象データ型を実装する
  • は、複数の「ノード」を格納するように実現される.各ノードは、自分の次のノードを指します.
  • ノードは、記憶値そのものを表す「データ」と、次のノードを指す「ポインタ」からなる.
  • インプリメンテーション

    # 노드 구현
    class Node:
    	def __init__(self, data, next):
        	self.data = data
            self.next = next
    
    node1 = Node("hi")
    node2 = Node(1120)
    node3 = Node("merong")
    
    # 노드 연결
    node1.next = node2
    node2.next = node3
    
    # 링크드리스트 구현
    class LinkedList:
        def __init__(self) :
            self.start = None # 시작 정점
            self.end = None # 끝 정점
            # 연결리스트에 아무런 정점도 들어있지 않은 상태. 배열에서 myList=[]와 같은 의미
        
        
        ### 조회
        def getNode(self, pos): # pos에 위치하는 노드 조회
            if pos < 0:  
                return None  
            node = self.start
            # 시작 정점부터 순차적으로 보기 위해 시작 정점을 넣어줌
            while pos > 0 and node != None:  
            # pos가 0보다 크고 node가 존재할 경우에 반복
                node = node.next  
                # 시작 정점부터 순차적으로 검사
                pos -= 1
            # pos = 0이 되면 해당값에 도달. 
            return node  # 해당값 return
            
        def getList(self) : # 링크드리스트를 배열로 return
            result = []
            current = self.start
            while current != None:
                result.append(current.data)
                current = current.Next
            return result
    
    
        ### 삽입
        def addFront(self, data) : # 맨 앞에 삽입
            ### 연결리스트가 비어있는 경우
            if self.start == None and self.end == None:
                elem = Node(data, None) 
                # 다음값이 없기에 포인터는 None
                self.start = elem
                self.end = elem
                # 첫번째 값이기 때문에 시작 정점과 끝 정점은 동시에 elem이 들어감
                
            ### 연결리스트가 비어있지 않은 경우
            ### 왼쪽으로 삽입되는 경우, 삽입되는 값이 새로운 시작 정점이 된다.
            else:
                elem = Node(data, self.start) 
                # 따라서 다음 값을 가리키는 포인터에는 self.start를 넣는다.
                self.start = elem
                # 시작 정점을 새로운 값이 차지
    
        def addBack(self, data) : # 맨 뒤에 삽입
            ### 비어있는 경우 (addLeft와 동일)
            if self.start == None and self.end == None:
                elem = Node(data, None)
                self.start = elem
                self.end = elem
                
            ### 비어있지 않은 경우
            ### 오른쪽으로 삽입되는 경우, 제일 끝에 들어가므로 다음값은 존재하지 않음
            else:
                elem = Node(data, None) 
                # 따라서 다음 값을 가리키는 포인터는 None
                self.end.Next = elem
                # 기존 끝 정점의 next에 elem 넣어주기
                self.end = elem
                #링크드리스트의 마지막을 새로운 값이 차지
                
        def addNode(self, pos, data):  # 원하는 위치(pos)에 삽입
            prev = self.getNode(pos - 1) # 추가하려는 위치 바로 앞의 노드
            if prev == None: 
            # 맨 앞에 추가하는 경우
                self.start = Node(data, self.start)  
                # 현재 값이 시작 정점 차지. (next값은 원래 시작 정점)
            else:
                node = Node(data, prev.next)  
                # '기존 prev의 다음 위치를 가리키는 포인터'를 가진 노드 추가
                prev.next = node  
                # prev의 next는 node(추가한 노드)를 가리키도록 한다.
        
        
        ### 삭제
        def deleteNode(self, dataToDelete):
            node = self.start
            start = node
            prev = None # 시작 정점부터 보기 때문에 이전 값은 아직 None
            while node: # 시작 정점부터 순차적으로 반복문 시작
                if node.data == dataToDelete: 
                # Node의 값이 지우려는 값일 때
                    if prev == None: 
                    # 지우려는 Node가 시작정점이여서 앞에 아무것도 없을 때
                        self.start = node.next 
                        # 본인만 지우니 다음 값이 시작 정점이 된다.
                    else: 
                    # 지우려는 Node가 시작정점이 아닐 때 (=앞에 prev가 있을 때)
                    # 앞, 뒤 연결해주고, 사이 연결 끊기
                        prev.next = node.next 
                        # 이전 노드와 현재값의 다음 노드 연결(앞-뒤 연결)
                        if prev.next == None:
                        # 이전 노드의 다음 값이 없다면 (=이전 노드가 끝 정점이 되었다면)
                            self.end = prev 
                            # prev를 끝 정점으로 지정
                prev = node 
                node = node.next # prev, node를 각각 다음 값으로 넘겨서 계속 반복
            return start

    ¥2,000の長所

  • 資料の挿入/削除が便利です.
  • 欠点

  • 特定の場所の資料を検索するのは面倒です.
    (配列は常に1つの値を一度に検索できますが、リンクリストで検索される値は開始点から遠いほど演算回数が多くなります.)
  • 配列とリンクリストの違い


    ≪配列|Array|emdw≫:順序接続された空間にデータの構造がリストされます.
    リンクリスト:独立したデータを接続する任意の構造
    ->すべての要素を巡る演算は、メモリの特性上、より有利に配置されます.