Knowledge Map
DataStructure in Python[연결리스트] 본문
1. 연결리스트(Linked List)
연결리스트는 노드(node)와 링크(link)로 구성된다.
노드는 데이터를 담고 링크는 각 노드를 연결한다.
연결리스트는 메모리가 필요하면 할당, 필요없으면 해제하는 식으로 메모리 관리가 가능하기 때문에 배열처럼 여분의 공간을 마련할 필요가 없어 메모리를 절약할수 있다.
연결리스트는 배열처럼 메모리에 연속적으로 할당되지 않고 임의로 할당된 뒤에 각 요소들을 링크로 연결한다.
연결리스트는 각 노드별로 링크의 개수와 링크의 연결 상태에 따라 단순연결리스트, 환형 연결 리스트, 이중 연결리스트, 이중 환형 연결리스트 등이 있다.
1.1 단순 연결 리스트(Simple Linked List)
단순 연결 리스트는 정보를 저장하는 노드와 바로 다음 노드를 가리키는 링크하나로 구성된다.
파란색 : 데이터가 들어가는 부분
하얀색 : 다음 노드를 가리키는 링크
단순 연결리스트는 사용자가 첫번째 노드를 알고 있어야 연결 리스트에 진입할수 있으며 마지막 노드는 아무것도 가리키지 않게 한다.
파이썬2 로 구현한 SimpleLinkedList
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | # 파이썬 버전 2.7 # 노드를 classNode로 표현하였다. # 데이터를 담는 멤버변수 self.data # 링크를 담는 멤버 변수 self.next 를 초기화 한다. class Node: def __init__(self, data, next=None): self.data = data self.next = next # init_list() 함수에서 전역으로 노드를 생성하고 각 노드의 링크를 다음 노드를 가리킨다. def init_list(): global node1, node2, node3, node4 node1 = Node(1) node2 = Node(2) node3 = Node(3.333) node4 = Node("four") node1.next = node2 node2.next = node3 node3.next = node4 def Main(): init_list() node = node1 print node, node1, node2, node3, node4 while node: print node.data node = node.next Main() | cs |
실제 실행을 해보면 다음과 같이 생성되는 것을 볼수 있다.
파이썬은 변수의 자료형을 따로 지정하지 않기 때문에 노드에 다양한 형태의 데이타를 넣을수 있는 장점이 있다.
1.2 단순연결리스트 삭제
연결리스트는 간단한 링크의 조작으로 노드의 삽입과 삭제가 가능하다.
검은색 노드를 삭제 하고 싶을때 이전노드의 링크를 다음 노드를 가리키게 링크를 변경하고 삭제할 노드를 메모리에서 해제하면 삭제가 완료된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | def delete_node(del_data): global node1 pre_node = node1 next_node = pre_node.next if pre_node.data == del_data: node1 = next_node del pre_node # pre_node의 타입은 instance이다. # del => 리스트, 리스트 요소를 삭제하는 명령어. # 참고로 한글 주석이라서 그대로 복붙하면 에러날수 있으니 주의 return node1 while next_node: if next_node.data == del_data: pre_node.next=next_node.next del next_node break pre_node = next_node next_node=next_node.next return node1 | cs |
각 노드에 전체 자료가 다 들어가 있는게 아니라 각 노드는 주소만 가지고 있을 뿐이다.
node1에는 객체에 대한 주소가 들어가 있으며 그 주소를 통해 값을 참조한다.
만약 동일 객체의 주소를 받은 다른 변수가 있어 그 변수에서 해당 주소 값으로 타고 들어가서 값을 수정하면
node1또한 그 값이 변화하게 되는 것이다.
1.3 단순연결리스트 추가
추가할 노드를 생성한 뒤 링크를 수정하면 된다.
가장 앞부분에 새로운 노드를 생성, 이런 형태의 자료구조를 스택이라고 한다.
(추가되는 새로운 자료를 간편함을 위해 제일 앞부분에 추가되도록 했다한다.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | class Node: def __init__(self, data, next=None): self.data = data self.next = next def init_list(): global node1, node2, node3, node4 node1 = Node(1) node2 = Node(2) node3 = Node(3.333) node4 = Node("four") node1.next = node2 node2.next = node3 node3.next = node4 def delete_node(del_data): global node1 pre_node = node1 next_node = pre_node.next if pre_node.data == del_data: node1 = next_node del pre_node #Type of pre_node is instance # del can delete list or a list item return node1 while next_node: if next_node.data == del_data: pre_node.next=next_node.next del next_node break pre_node = next_node next_node=next_node.next return node1 def insert_node(ins_data): global node1 new_node = Node(ins_data) new_node.next = node1 node1 = new_node return node1 def print_list(): global node1 node = node1 while node: print node.data node = node.next def Main(): init_list() print_list() node = delete_node(2) print "after delete","===="*20 print_list() node = insert_node(1000000000) print "after delete","===="*20 print_list() Main() | cs |
1.4 환형 연결 리스트(Circualr Lined List)
이것은 단순 연결리스트의 마지막 노드 링크가 첫번째 노드를 가리키는 형태를 말한다. 환형 연결 리스트는 임의의 노드에서 모든 노드에 접근이 가능하다.
만드는 방법은 마지막 노드가 첫번째 노드를 가리키도록 초기화를 행하면 된다. 다만 이렇게 되면 링크가 루프가 되어있기 때문에노드 검색, 리스트 출력할 때 무한 루프에 빠지지 않도록 주의해야한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | #-*- coding: UTF-8 -*- import re class Node: def __init__(self, data, next=None): self.data = data self.next = next def init_list(): global node1, node2, node3, node4 node1 = Node(1) node2 = Node(2) node3 = Node(3.333) node4 = Node("four") node1.next = node2 node2.next = node3 node3.next = node4 node4.next = node1 <======= 다시 처음으로 연결 # circular linked list # 이걸 while문으로 출력하게 하면 무한 루프를 돌게 된다. def delete_node(del_data): global node1 pre_node = node1 next_node = pre_node.next if pre_node.data == del_data: node1 = next_node del pre_node #Type of pre_node is instance # del can delete list or a list item return node1 while next_node: if next_node.data == del_data: pre_node.next=next_node.next del next_node break pre_node = next_node next_node=next_node.next return node1 def insert_node(ins_data): global node1 new_node = Node(ins_data) new_node.next = node1 node1 = new_node return node1 def print_list(): global node1 node = node1 while node: print node.data node = node.next def Main(): init_list() print_list() node = delete_node(2) print "================== after delete","===="*20 print_list() node = insert_node(1000000000) print "================== after insert","===="*20 print_list() Main() | cs |
1.5 이중 연결 리스트(Doubly Lined List)
이중연결 리스트는 이전 노드를 가리키는 노드와 다름 노드를 가리키는 링크, 2개의 링크가 존재한다.
앞뒤 노드 링크를 모두 가지고 있어서 단순 연결 리스트보다 유연하게 동작한다.
1.6 이중 연결 리스트 삭제
1.7 이중 연결 리스트 추가
아래의 코드는 생성, 삭제, 추가를 전부 포함한 코드이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | #-*- coding: UTF-8 -*- import re class Node: def __init__(self, data, next=None, pre = None): self.data = data self.next = next self.pre = pre def init_list(): global node1, node2, node3, node4 node1 = Node(1) node2 = Node(2) node3 = Node(3.333) node4 = Node("four") node2.pre = node1 node3.pre = node2 node4.pre = node3 node1.next = node2 node2.next = node3 node3.next = node4 def delete_node(del_data): global node1 pre_node = node1 next_node = pre_node.next next_node.pre = pre_node if pre_node.data == del_data: node1 = next_node next_node.pre = node1 del pre_node #Type of pre_node is instance # del can delete list or a list item return node1 while next_node: if next_node.data == del_data: pre_node.next=next_node.next next_node.next.pre = pre_node del next_node break pre_node = next_node next_node.pre = pre_node next_node=next_node.next return node1 def insert_node(ins_data): global node1 new_node = Node(ins_data) new_node.next = node1 node1.pre = new_node node1 = new_node return node1 def print_list(): global node1 node = node1 while node: print node.data node = node.next def Main(): init_list() print_list() node = delete_node(2) print "=========================================== after delete","===="*20 print_list() node = insert_node(1000000000) print "=========================================== after insert","===="*20 print_list() Main() | cs |
이중연결의 경우에는 앞,뒤로는 2개의 링크 조작을 하면되지만 중간에 할경우에는 링크 조작을 총 4개를 행해야 한다.
'PYTHON' 카테고리의 다른 글
DataStructure in Python[Selection Sort] (0) | 2016.05.07 |
---|---|
DataStructure in Python[큐&스택] (0) | 2016.05.07 |
lxml, python-docx 설치 관련 (0) | 2016.04.30 |
파이썬 자료 구조 (0) | 2016.04.30 |
주말 정리 과제 (0) | 2016.04.29 |