일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 자료구조
- 공부정리
- 데이터분석전문가가이드
- MySQL
- 당신이 몰랐던 진화론
- Hacker Rank
- python
- ADsP
- Joseph Samuel Nye Jr.
- Progate
- Baekjoon
- 조지프 나이
- ADP
- EBS
- 빅데이터
- 누가 진정한 리더인가
- K-MOOC
- 정치학
- Great Minds
- 후기
- Udemy
- 코테
- 알고리즘
- KMOOC
- 백준
- 위대한 수업
- 미분적분학
- 데이터분석전문가
- CNN10
- 맛집
Archives
- Today
- Total
ㅇ
[Udemy] JavaScript 알고리즘 & 자료구조 마스터클래스_Section 20 본문
* 수업은 JS 기반이지만 Python으로 구현
Section 20
이중 연결 리스트 소개
- head, tail, length 등의 특성을 가진 자료구조이다.
- 노드들로 이루어져 있으며, 각 노드는 값과 이전 노드와 다음 노드를 가리키는 포인터를 갖고 있다.
- 단일 연결 리스트보다 접근에 융통성이 있지만, 메모리를 더 많이 사용한다.
push method 소개
- 주어진 값을 받아들여 새로운 노드를 만든다.
- 만약 head 값이 비어있다면, head와 tail을 새롭게 만든 노드로 설정한다.
- 만약 리스트가 비어있지 않다면, tail의 next를 새롭게 만든 노드로 설정한다.
- 새롭게 만든 노드의 prev를 tail로 설정한다.
- tail 값을 새롭게 만든 노드로 설정한다.
- 리스트 길이를 하나 늘린다.
pop method 소개
- 만일 리스트가 비어있다면, undefined를 반환한다.
- 그렇지 않다면, 현재 tail을 반환하기 위해 변수에 저장한다.
- 만약 리스트의 길이가 1이라면, head와 tail 모두 null로 설정한다.
- tail을 prev 노드로 설정한다.
- 새로 설정된 tail의 next를 null로 설정한다.
- 원래 tail의 prev를 null로 설정하여 리스트와의 모든 연결을 해제한다.
- 리스트 길이를 하나 줄인다.
- 변수에 저장해둔 삭제한 tail을 반환한다.
shift method 소개
- 만일 리스트가 비어있다면, undefined를 반환한다.
- 그렇지 않다면, 현재 head를 반환하기 위해 변수에 저장한다.
- 만약 리스트의 길이가 1이라면, head와 tail 모두 null로 설정한다.
- head를 head의 next로 설정한다.
- head의 prev를 null로 설정한다.
- 원래 head의 next를 null로 설정하여 리스트와의 모든 연결을 해제한다.
- 리스트 길이를 하나 줄인다.
- 변수에 저장해둔 삭제한 head를 반환한다.
unshift method 소개
- 리스트 시작 위치에 추가하려는 노드를 인자로 받아들이는 함수를 정의한다.
- 만약 head값이 없다면 리스트가 비어있다는 것이므로, head와 tail을 새롭게 만들어지는 노드를 가리키도록 정한다.
- 만약 리스트가 비어있지 않다면
- head의 prev를 새롭게 만들어지는 노드로 설정한다.
- 새롭게 만들어진 노드의 next를 현재의 head값을 가리키게 한다.
- head가 새롭게 생성된 노드를 가리키도록 생성하고, 길이를 하나 늘린다.
- 그 연결 리스트를 반환한다.
get method 소개
- 함수는 입력된 숫자를 인덱스 인자로 받는다.
- 인덱스 범위에 따라 다음과 같은 엣지 케이스가 있을 수 있으며, Null을 반환한다.
- 음수
- 리스트의 길이보다 크거나 같을 경우
- 인덱스값에 따라 head 혹은 tail을 활용한다.
- 만약 인덱스가 리스트 길이의 반보다 작거나 같다면 head에서 시작해서 next를 이용한다.
- 만약 인덱스가 리스트 길이의 반보다 크다면, tail에서 시작해서 prev를 이용한다.
- 루프를 통해 인덱스가 지정하는 위치에 이를때까지 이동한 후, 해당 인덱스 위치의 노드를 반환한다.
set method 소개
- 변수를 만들어 set 함수에 입력된 인덱스 값을 넣은 get 함수의 결과값으로 설정한다.
- get 함수가 유효한 노드값을 반환하면, 해당 노드의 값을 set 함수에 입력된 데이터 값으로 바꾼 후, True를 출력한다.
insert method 소개
- 만약 인덱스가 0보다 작거나 리스트 길이보다 크다면 False를 반환한다.
- 만약 인덱스가 리스트의 길이와 같다면, push 함수를 사용하여 리스트 마지막에 새로운 노드를 삽입한다.
- 만약 인덱스가 0이라면, unshift 함수를 활용해 리스트 맨 앞에 새로운 노드를 삽입하면 된다.
- 위의 모든 경우가 아니라면, get 함수를 활용해 인덱스 - 1 위치의 next를 생성한 새 노드로 가리키게 한다.
- 새 노드의 next를 원래 위치의 노드를, prev를 인덱스 - 1 위치를 가리키게 한다.
- 원래 위치의 노드의 prev를 새 노드를 가리키게 한다.
- 전체 길이를 1 증가시키고, True를 반환한다.
remove method 소개
- 인덱스 값이 0보다 작거나 혹은 리스트 길이보다 클 경우 Undefined를 반환한다.
- 인덱스 값이 리스트 길이 - 1과 같다면, pop 함수를 활용한다.
- 인덱스 값이 0이라면 shift 함수를 활용한다.
- 위의 모든 경우가 아니라면, get 함수를 활용해 삭제할 노드의 next와 prev를 연결한다.
- 삭제할 index 위치의 prev와 next를 Null로 설정한다.
- 리스트 길이를 1 감소하고, 제거된 노드를 반환한다.
method 구현
# 노드 정의하기
class Node:
# constructor
def __init__(self, val):
self.val = val
self.next = None
self.prev = None
# 이중연결리스트 class 정의
class DoublyLinkedList:
# constructor
def __init__(self):
self.head = None
self.tail = None
self.length = 0
# 리스트 요소를 탐색하는 과정을 보기 위한 함수
def traverse(self):
tmp = self.head
while(tmp):
print(tmp.val)
tmp = tmp.next
# instance method
def push(self, val):
newNode = Node(val)
# 리스트가 비어있는 상태
if self.head is None:
self.head = newNode
self.tail = self.head
# 리스트가 비어있지 않은 상태
# 현재 tail의 next가 새로운 노드를 가리키게 하고
# 새로운 노드의 prev가 현재 tail을 가리키게 하고
# tail을 새로운 노드로 바꾼다
else:
self.tail.next = newNode
newNode.prev = self.tail
self.tail = newNode
self.length += 1
return self
# instance method
def pop(self):
if self.head is None:
return 'Undefined'
tmp = self.tail
if self.length == 1:
self.head = None
self.tail = None
else:
self.tail = tmp.prev
self.tail.next = None
# 원래 tail의 prev 값을 None으로 두어
# 리스트와의 연결 모두를 끊어낸다.
tmp.prev = None
self.length -= 1
return tmp.val
# instance method
def shift(self):
if self.head is None:
return 'Undefined'
tmp = self.head
if self.length == 1:
self.head = None
self.tail = None
else:
self.head = tmp.next
self.head.prev = None
tmp.next = None
self.length -= 1
return tmp.val
# instance method
def unshift(self, val):
newNode = Node(val)
if self.head is None:
self.head = newNode
self.tail = newNode
else:
tmp = self.head
tmp.prev = newNode
newNode.next = tmp
self.head = newNode
self.length += 1
return self
# instance method
def get(self, index):
self.index = index
if (self.index < 0) or (self.length <= self.index):
return None
else:
mid = int(self.length / 2)
if self.index <= mid:
# 확인 문구, 이후에 지우기
# print('from head')
counter = 0
tmp = self.head
while(counter != self.index):
tmp = tmp.next
counter += 1
else:
# 확인 문구, 이후에 지우기
# print('from tail')
counter = self.length - 1
tmp = self.tail
while(counter != self.index):
tmp = tmp.prev
counter -= 1
return tmp
# instance method
def set(self, index, val):
self.index = index
tmp = self.get(self.index)
if tmp is None:
return False
else:
tmp.val = val
return True
# instance method
def insert(self, index, val):
self.index = index
if (self.index < 0) or (self.length < self.index):
return False
elif self.index == 0:
return not not self.unshift(val)
elif self.index == self.length:
return not not self.push(val)
else:
newNode = Node(val)
former = self.get(self.index - 1)
later = former.next
former.next = newNode
newNode.next = later
newNode.prev = former
later.prev = newNode
self.length += 1
return True
# instance method
def remove(self, index):
self.index = index
if (self.index < 0) or (self.length <= self.index):
return 'Undefined'
elif self.index == 0:
return self.shift()
elif self.index == self.length - 1:
return self.pop()
else:
tmp = self.get(self.index)
former = tmp.prev
later = tmp.next
former.next = later
later.prev = former
tmp.prev = None
tmp.next = None
self.length -= 1
return tmp.val
# 노드 선언
print('---Make Node---')
DL = DoublyLinkedList()
DL.push('Hello')
DL.push('You')
DL.push('GoodBye')
DL.push('!!!')
DL.push('><')
DL.push('><')
print('\n---Double Linked List---')
DL.traverse()
print('\n---pop fcn---')
print(DL.pop())
# 리스트 tail, 리스트 길이 출력
print('tail: ', DL.tail.val)
print('length: ', DL.length)
print('\n---Double Linked List---')
DL.traverse()
print('\n---shift fcn---')
print(DL.shift())
# 리스트 head, 리스트 길이 출력
print('head: ', DL.head.val)
print('length: ', DL.length)
print('\n---Double Linked List---')
DL.traverse()
print('\n---unshift fcn---')
DL.unshift(':)')
# 리스트 head, 리스트 길이 출력
print('head: ', DL.head.val)
print('length: ', DL.length)
print('\n---Double Linked List---')
DL.traverse()
print('\n---get fcn---')
num = DL.length
print('num: ', num)
print(DL.get(num))
print('\n')
num = -3
print('num: ', num)
print(DL.get(num))
print('\n')
num = 1
print('num: ', num)
print(DL.get(num).val)
# get 함수에서 주석을 해제하면, head에서 시작한지 tail에서 시작했는지 확인할 수 있음
print('\n---get fcn check---')
for i in range(DL.length):
DL.get(i).val
print('\n---set fcn---')
print(DL.set(5, ';/'))
DL.traverse()
print('\n')
print(DL.set(4, ';/'))
DL.traverse()
print('\n---insert fcn---')
num = 8
print('num: ', num)
print(DL.insert(num, '=t='))
print('length: ', DL.length)
DL.traverse()
print('\n')
num = 0
print('num: ', num)
print(DL.insert(0, '=t='))
print('length: ', DL.length)
DL.traverse()
print('\n')
num = DL.length
print('num: ', num)
print(DL.insert(num, '=t='))
print('length: ', DL.length)
DL.traverse()
print('\n')
num = 5
print('num: ', num)
print(DL.insert(num, '=t='))
print('length: ', DL.length)
DL.traverse()
print('\n---remove fcn---')
num = -10
print('num: ', num)
print(DL.remove(num))
DL.traverse()
print('\n')
num = 10
print('num: ', num)
print(DL.remove(num))
DL.traverse()
print('\n')
num = 0
print('num: ', num)
print(DL.remove(num))
DL.traverse()
print('\n')
num = DL.length - 1
print('num: ', num)
print(DL.remove(num))
DL.traverse()
print('\n')
num = 3
print('num: ', num)
print(DL.remove(num))
DL.traverse()
자료구조: 빅오 복잡도
- Insertion: O(1)
- Removal: it depends ... O(1)
- Searching: O(N) technically, O(N/2)
- Access: O(N)
반응형
'내 생각 > 강의' 카테고리의 다른 글
[Udemy] JavaScript 알고리즘 & 자료구조 마스터클래스_Section 22 (0) | 2023.08.11 |
---|---|
[Udemy] JavaScript 알고리즘 & 자료구조 마스터클래스_Section 21 (0) | 2023.08.08 |
[Udemy] JavaScript 알고리즘 & 자료구조 마스터클래스_Section 19 (0) | 2023.07.25 |
[Udemy] JavaScript 알고리즘 & 자료구조 마스터클래스_Section 18 (0) | 2023.07.24 |
[EBS_위대한 수업] [경제학] 리처드 도킨스, 당신이 몰랐던 진화론_5강 과학이라는 마법 (0) | 2023.07.10 |
Comments