#자료구조의 종류
- 배열(Array)
- 연결리스트(Linked List)
- 스택(Stack)
- 큐(Queue)
- 그래프(Graph)
- 트리(Tree)
1. 배열(Array) #파이썬에는 없는 개념(list와 그나마 가장 유사함)
- 가장 기본적인 자료구조, 선형 데이터구조
- 배열 생성되는 순간 인덱스 부여(인덱스 표기법)
- 배열 크기 고정
- 배열크기가 고정되어 있어 데이터를 추가, 삭제과정이 비효율적
~ 더 큰 배열을 추가로 만들고 이전 값을 복사한 후 새로운 값 추가
~ 더 작은 배열을 추가로 만들고 삭제할 값을 빼고 이전 값을 복사
- 데이터가 삭제되면 남은 공간이 생겨 메모리 낭비 발생
- 하나의 변수명으로 여러 데이터를 관리가능함.
2. 연결리스트(Linked List)
2-1. 단방향 연결 리스트
- 선형 데이터구조
- 데이터는 메모리의 임의 공간에 저장
- 데이터의 순서에 따라 노드의 주소를 이용하여 서로 연결시킨 구조(값뿐만 아니라 다음에 올 값의 위치정보도 함께 나열)
~ 노드 = 데이터부+주소부
- 새로운 데이터의 추가, 삭제가 용이함.(배열과 다르게 추가, 삭제 시 재구성 필요 없음.)
- 배열과 다르게 추가, 삭제 시 재구성 필요 없음.
- 메모리의 효율적 사용 가능함.
- 노드의 주소가 끊어지면 다음 노드를 찾기가 어려움.
- 조회 속도가 상대적으로 느림.
class Node :
def __init__(self, data) :
self.data = data #값
self.next = None #다음 노드의 위치 정보 - 주소부에 들어가는 것!!
class LinkedList :
def __init__(self) :
self.head = None #맨 처음 노드를 가리킴 (값+위치)
def print(self) :
tmp = self.head
while tmp :
print(tmp.data, end = ", ")
tmp = tmp.next
def firstAdd(self, new_data) : #시간복잡도 O(1)
new_node = Node(new_data)
new_node.next = self.head
self.head = new_node
def lastAdd(self, new_data): #시간복잡도 O(n)
new_node = Node(new_data) #new_data의 위치정보
tmp = self.head # 맨 앞 node
while tmp.next :
tmp = tmp.next
tmp.next = new_node
def middleAdd(self, index, new_data):
index = index - 1 # 이전 노드
tmp = self.head
while index > 0 and tmp !=None :
tmp = tmp.next
index = index - 1
#tmp : 추가하려는 노드의 이전 노드
new_node = Node(new_data)
new_node.next = tmp.next #새 노드의 위치 정보에 다음 노드 정보(원래 그 위치에 있던 노드의 위치 정보) 삽입
tmp.next = new_node # 이전 노드 위치정보에 새 위치 정보 삽입
def firstDelete(self) :
tmp = self.head
self.head = tmp.next
def lastDelete(self):
tmp = self.head
while tmp.next.next :
tmp = tmp.next
#tmp : 맨 마지막 노드의 이전 노드
tmp.next = None
def middleDelete(self, index):
if index == 0 :
tmp = self.head
self.head = tmp.next
else :
index = index -1# 이전 노드
tmp = self.head
while index > 0 and tmp !=None :
tmp = tmp.next
index = index - 1
tmp.next = tmp.next.next # 노드 위치 정보에 다다음 위치 정보 삽입()
def getData(self, index) :
tmp = self.head
while index > 0 and tmp !=None :
tmp = tmp.next
index = index - 1
return tmp.data
ll = LinkedList()
zero = Node(9) #one 변수 : node(9)의 위치 정보
one = Node(13) #two 변수 : node(13)의 위치 정보
two = Node(7)
three = Node(20)
ll.head = zero #시작 숫자 9
zero.next = one # 다음 숫자 13의 위치 정보(9 -> 13)
one.next = two #9 -> 13 -> 7
two.next = three #9 -> 13 -> 7 ->20
'''
ll.firstAdd(15) #맨 앞에 15 추가
ll.lastAdd(10) # 맨 뒤에 10 추가
ll.middleAdd(2, 5) #2번 위치에 5 추가
'''
##ll.firstDelete() #맨 앞 삭제
##ll.lastDelete() #맨 뒤 삭제
##ll.middleDelete(2)
ll.print()
print(ll.getData(1))
2-2.양방향 연결 리스트(이중 연결 리스트)
- 3개의 구성요소(앞주소, 뒷주소, 값)
- 이전 노드를 알고 있으므로 맨 끝 노드를 삭제할 때 바로 삭제 가능함.
- 단방향 연결 리스트보다 더 복잡하지만, 효율성이 높음
class Node :
def __init__(self, data, prev=None, next=None) :
self.data = data
self.prev = prev
self.next = next
class DoubleLinkedList :
def __init__(self) :
self.head = None #맨 처음 노드를 가리킴 (위치+값+위치)
self.tail = None #맨 끝 노드를 가리킴(위치+값+위치)
def print(self) : #화면 출력
tmp = self.head
while tmp :
print(tmp.data, end = ", ")
tmp = tmp.next
def firstAdd(self, new_data) : #시간복잡도 O(1)
if self.head == None : #노드가 하나도 없을 때
new_node = Node(new_data)
self.head = new_node
self.tail = new_node
else : #노드가 한 개 이상 있을 때
new_node = Node(new_data)
tmp = self.head
tmp.prev = new_node #기존에 맨 앞에 있던 노드의 prev 위치정보에 새 노드의 위치정보 넣기
new_node.next = tmp #새 노드의 next 위치정보에 기존 노드의 prev 위치정보 넣기
self.head = new_node
def lastAdd(self, new_data) : #시간복잡도 O(1)
if self.head == None : #노드가 하나도 없을 때
new_node = Node(new_data)
self.head = new_node
self.tail = new_node
else: #노드가 한 개 이상 있을 때
new_node = Node(new_data)
tmp = self.tail #tmp: 맨 마지막 노드
tmp.next = new_node #기존에 맨 뒤에 있던 노드의 next 위치정보에 새 노드의 위치정보 넣기
new_node.prev = tmp #새 노드의 pre 위치정보에 기존 노드의 위치정보 넣기
self.tail = new_node
def middleAdd(self, index, new_data):
index = index - 1 # 이전 노드
tmp = self.head
while index > 0 and tmp !=None :
tmp = tmp.next
index = index - 1
#tmp : 추가하려는 노드의 이전 노드
new_node = Node(new_data)
new_node.next = tmp.next #새 노드의 next 위치 정보에 다음 노드 정보(원래 그 위치에 있던 노드의 위치 정보) 삽입
tmp.next.prev = new_node # 다음 노드(원래 그 위치에 있던 노드)의 prev 위치 정보에 새 노드 위치정보 삽입
tmp.next = new_node # 이전 노드 위치정보에 새 위치 정보 삽입
new_node.prev = tmp#새 노드의 prev 위치 정보에 이전 노드 위치정보 삽입
def firstDelete(self) :
if self.head.prev == None and self.head.next ==None : #노드가 한 개일 때
self.head = None
self.tail = None
else : #노드가 두 개 이상일 때
tmp = self.head
self.head = tmp.next
tmp.next.prev = None
def lastDelete(self) :
if self.head.prev == None and self.head.next ==None : #노드가 한 개일 때
self.head = None
self.tail = None
else : #노드가 두 개 이상일 때
tmp = self.tail.prev #이전 노드
tmp.next = None
self.tail = tmp
def reverseprint(self) : #역순 출력
tmp = self.tail
while tmp != None :
print(tmp.data, end = ", ")
tmp = tmp.prev
dll = DoubleLinkedList()
dll.firstAdd(10)#10
dll.firstAdd(5) #5, 10
dll.lastAdd(7) #5, 10, 7
dll.lastAdd(15) #5, 10, 7, 15
dll.middleAdd(2, 11) #5, 10, 11, 7 , 15
dll.firstDelete() #10, 11, 7, 15
dll.lastDelete() #10, 11, 7
dll.print()
print()
dll.reverseprint() #7, 11, 10
'파이썬(PYTHON) > 자료구조' 카테고리의 다른 글
[Python] 큐, 그래프, 트리 (0) | 2022.08.21 |
---|---|
[Python] 자료구조 - 스택 (0) | 2022.08.20 |
[Python] 정렬 (0) | 2022.08.07 |
[Python] 재귀호출, 시간복잡도 (0) | 2022.08.06 |