배열이란?
컴퓨터의 물리적 메모리는 일정한 크기의 방처럼이해를 할 수 있다. 한 개의 방에 크기에 따라서 여러 변수들을 저장할 수 있게 된다. (이 정도는 알아야 한다…)
그렇다면 배열이란 물리적으로 붙어있는(연속적인) 메모리의 나열 이라고 생각하면 쉽다.
array = []
otherarray = list()
이렇게 쓰게 되는데 이러한 배열은 RAM(Random Access Memory)로 index를 알 수 있다면 무조건 적으로 접근이 가능하다.
array = ["a","b","c"]
a = array[0]
이러한 배열은 장단점이 분명하게 존재한다.
특징
- Create : 선언하기 쉽고 쓰기 간편하다. 다만 배열의 크기가 정해진 경우 O(n)의 시간만큼의 시간이 걸린다.
- Read :만약 위치를 정확하게 명확하게 알수 있다면 원하는 데이터에 O(1) 시간안에 접근이 가능하다.
- Update : 특정 위치에 삽입을 하는 경우 찾는데 O(1) 수정시 O(1)의 시간이 걸리게 된다.
- Delete : 특정 위치에 삭제를 하는 경우 찾는데 O(1) 삭제시 O(n)의 시간이 걸리게 된다.
LinkedList : 연결리스트
배열은 생성과 읽기가 굉장히 쉬운 자료구조이다. 하지만 프로그래밍에서 만들고 읽는 것만 하는 부분은 없다. (굉장히 적다) 해서 특정 조건하에 생성은 많이 되질 않고 수정과 삭제가 빈번한 상황에서 특별히 좋은 성능을 가지는 자료구조가 바로 연결리스트이다.
특징
- Create : 특정 위치를 고정해서 생성하는 경우에 O(1) 시간안에 가능하다. 또한 크기가 정해져 있지 않아 배열을 수정하는 시간이 걸리지 않는다.
- Read : 특정 위치를 찾기 위해서 최악의 경우 모든 Node를 탐색하여 O(n)의 시간이 걸린다.
- Update : 특정 위치에 삽입을 하는 경우 찾는데 O(n) 수정하는데 O(1) 시간안에 가능하다.
- Delete : 특정 위치에 삽입을 하는 경우 찾는데 O(n) 삭제하는데 O(1) 시간안에 가능하다.
연결리스트의 개념
연결리스트는 Node를 기본으로 가진다.
class Node:
def __init__(self,value):
self.value = value
self.pointer = Node
Node는 자료를 나타내는 value와 다른 노드를 지칭할 수 있게 해주는 pointer로 구성이 된다. value는 Int, String, Double, Class등 여러 타입이 될 수 있다. pointer는 다른 노드를 지칭하게 된다.
Pointer
Node에 존재하는 pointer의 역할은 다른 Node를 가리키게 하는 것이다. NodeA를 읽게 된다면 자동적으로 다른 NodeB 혹은 NodeC를 가리키는 하나의 변수를 얻게 되는 것이다.
class Node:
def __init__(self,value):
self.value = value
self.pointer = Node
NodeA = Node(10)
NodeB = Node(11)
NodeA.pointer = NodeB
위 코드와 같이 NodeA와 NodeB가 존재한다고 했을 때 NodeA.pointer = NodeB를 했을 때, NodeA의 pointer에는 NodeB의 주소값이 들어가게 되고, 이를 통해 다음 값을 알 수 있게 된다.
SingleLinkedList
SingleLinkedList는 하나의 노드에서 시작해서 한 방향으로만 추가를 하는 형태를 의미한다.
class Node:
def __init__(self,value):
self.value = value
self.pointer = Node
rootNode = Node(0)
headNode = Node(-1)
headNode = rootNode
for i in range(10):
addNode = Node(i)
addNode.pointer = rootNode.pointer
rootNode.pointer = addNode
DoubleLinkedList
SingleLinkedList는 하나의 노드에서 시작해서 양 방향으로만 추가를 하는 형태를 의미한다.
class Node:
def __init__(self, value):
self.value = value
self.head = None
self.tail = None
for i in range(1,10):
addNode = Node(i)
if rootNode.tail ==null:
addNode.head = rootNode
rootNode.tail = addNode
else:
addNode.head = rootNode
addNode.tail = rootNode.tail
rootNode.tail.head = addNode
rootNode.tail = addNode
과제
Answer
cclass Node:
def __init__(self, value):
self.value = value
self.up = None
self.down = None
self.left = None
self.right = None
def iter(self):
iterNode = self
rightflag = True
ret_str = ""
while True:
ret_str += str(iterNode.value) + " "
if iterNode.right !=None and rightflag:
iterNode = iterNode.right
elif iterNode.left !=None and not rightflag:
iterNode = iterNode.left
elif iterNode.right == None and iterNode.down !=None:
iterNode = iterNode.down
rightflag = False
elif iterNode.left == None and iterNode.down !=None:
iterNode = iterNode.down
rightflag =True
elif iterNode.right == None and iterNode.down == None:
break
return ret_str
oneNode = Node(1)
leftTop = oneNode
rightiter = oneNode
for i in range(2,26):
addNode = Node(i)
if i % 5 == 1:
addNode.up = leftTop
leftTop.down = addNode
leftTop = addNode
rightiter = addNode
elif rightiter.value <5:
rightiter.right = addNode
addNode.left = rightiter
rightiter = addNode
elif rightiter == 5:
rightiter.right =addNode
addNode.left = rightiter
rightiter = addNode
else:
rightiter.right = addNode
addNode.left = rightiter
addNode.up = rightiter.up.right
addNode.up.down = addNode
rightiter = addNode
print(oneNode.iter())```