일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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
- EBS
- Progate
- ADsP
- ADP
- K-MOOC
- 미분적분학
- Joseph Samuel Nye Jr.
- CNN10
- Baekjoon
- Great Minds
- 데이터분석전문가
- 자료구조
- KMOOC
- 데이터분석전문가가이드
- 공부정리
- 당신이 몰랐던 진화론
- Udemy
- python
- 후기
- 맛집
- 누가 진정한 리더인가
- 위대한 수업
Archives
- Today
- Total
ㅇ
[Udemy] JavaScript 알고리즘 & 자료구조 마스터클래스_Section 19 본문
* 수업은 JS 기반이지만 Python으로 구현
Section 19
단일 연결 리스트 소개
- head, tail, length 등의 특성을 가진 자료구조이다.
- 노드들로 이루어져 있으며, 각 노드는 값과 다음 노드를 가리키거나 null 값을 가진 포인터를 갖고 있다.
- 인덱스가 없어 엘리베이터가 없는 고층 건물과 같다. 원하는 값이 나올 때까지 그 앞의 모든 값을 지나쳐야 한다.
- 임의 접근이 허용되지 않고, 각 노드는 넥스트 포인터를 통해 연결되어 있다.
- 새로운 항목을 추가하거나, 기존 항목을 제거하는 데에는 인덱스가 없으므로 더 쉽게 수행할 수 있다.
# 노드 정의하기
class Node:
# constructor
def __init__(self, val):
self.val = val
self.next = None
# 연결된 노드 정의하기
first = Node('Hi')
first.next = Node('There')
first.next.next = Node('How')
first.next.next.next = Node('are')
first.next.next.next.next = Node('you')
# 연결된 노드 값 확인하기
first.val
first.next.val
first.next.next.val
first.next.next.next.val
first.next.next.next.next.val
push method 소개
- 주어진 값을 받아들여 새로운 노드를 만든다.
- 만약 head값이 없다면 리스트가 비어있다는 것이므로, head와 tail을 새롭게 만들어지는 노드를 가리키도록 정한다.
- 만약 리스트가 비어있지 않다면, 마지막노드의 next를 새롭게 만들어지는 노드를 가리키게 하고, tail이 새롭게 생성된 노드를 가리키도록 생성하고, 길이를 하나 늘린다.
- 그 연결 리스트를 반환한다.
pop method 소개
- 만일 리스트에 아무것도 없는 경우 undefined 를 반환한다.
- tail에 도달할 때까지 리스트에 루프를 수행한다.
- 마지막에서 두 번째 노드의 next를 null로 설정하고, tail값을 마지막에서 두 번째 노드로 설정한다.
- 리스트 길이를 하나 줄인다.
- 방금 제거한 노드를 반환한다.
shift method 소개
- 만일 리스트에 아무것도 없는 경우 undefined 를 반환한다.
- 현재 head값을 변수에 저장한다.
- head가 head의 next를 가리키도록 설정한다.
- 리스트 길이를 하나 줄인다.
- 방금 제거한 노드를 반환한다.
unshift method 소개
- 리스트 시작 위치에 추가하려는 노드를 인자로 받아들이는 함수를 정의한다.
- 만약 head값이 없다면 리스트가 비어있다는 것이므로, head와 tail을 새롭게 만들어지는 노드를 가리키도록 정한다.
- 만약 리스트가 비어있지 않다면, 새롭게 만들어지는 노드의 next를 현재의 head값을 가리키게 하고, head가 새롭게 생성된 노드를 가리키도록 생성하고, 길이를 하나 늘린다.
- 그 연결 리스트를 반환한다.
get method 소개
- 함수는 입력된 숫자를 인덱스 인자로 받는다.
- 인덱스 범위에 따라 다음과 같은 엣지 케이스가 있을 수 있으며, Null을 반환한다.
- 음수
- 리스트의 길이보다 크거나 같을 경우
- 루프를 통해 인덱스가 지정하는 위치에 이를때까지 이동한 후, 해당 인덱스 위치의 노드를 반환한다.
set method 소개
- 함수는 인덱스와 값을 인자로 받는다.
- 원하는 노드를 찾기 위해 get 함수를 활용한다.
- 만약 노드를 찾을 수 없다면, False를 반환한다.
- 만약 노드를 찾았다면, 해당 노드 값을 인자로 받아들인 값으로 정하고, True를 반환한다.
insert method 소개
- 만약 인덱스가 0보다 작거나 리스트 길이보다 크다면 False를 반환한다.
- 만약 인덱스가 리스트의 길이와 같다면, push 함수를 사용하여 리스트 마지막에 새로운 노드를 삽입한다.
- 만약 인덱스가 0이라면, unshift 함수를 활용해 리스트 맨 앞에 새로운 노드를 삽입하면 된다.
- 위의 모든 경우가 아니라면, get 함수를 활용해 인덱스 - 1 위치의 next를 생성한 새 노드로 가리키게 한다.
- 새 노드의 next를 원래의 노드를 가리키게 한다.
- 전체 길이를 1 증가시키고, True를 반환한다.
remove method 소개
- 인덱스 값이 0보다 작거나 혹은 리스트 길이보다 클 경우 Undefined를 반환한다.
- 인덱스 값이 리스트 길이 - 1과 같다면, pop 함수를 활용한다.
- 인덱스 값이 0이라면 shift 함수를 활용한다.
- 위의 모든 경우가 아니라면, get 함수를 활용해 index - 1 위치의 next를 이전 노드의 .next.next로 설정한다.
- 리스트 길이를 1 감소하고, 제거된 노드를 반환한다.
reverse method 소개
- head와 tail을 교환한다.
- next, prev 변수를 만들어 Null 값을 넣어둔다.`
- node변수를 만들고, head 값을 배정한다.
- 다음의 과정을 교환한 tail부터 head까지 루프를 통해 리스트 전체에 적용한다.
- 현재 다루고 있는 값을 node 변수에 저장한다.
- 현재 node의 .next 값을 next 변수에 저장한다.
- 현재 node의 .next.next를 현재 node로 설정한다.
- 현재 node 값을 prev 변수에 저장하고, node 변수에 next값을 저장하여 다루는 값을 바꾼다.
method 구현
# 노드 정의하기
class Node:
# constructor
def __init__(self, val):
self.val = val
self.next = None
# 단일연결리스트 class 정의
class SinglyLinkedList:
# constructor
def __init__(self):
self.head = None
self.tail = None
self.length = 0
# instance method
def push(self, val):
newNode = Node(val)
# 리스트가 비어있는 상태
if self.head is None:
self.head = newNode
self.tail = self.head
# 리스트가 비어있지 않는 상태
# 현재 tail의 next가 새로운 노드를 가리키게 하고
# tail을 새로운 노드로 바꾼다
else:
self.tail.next = newNode
self.tail = newNode
self.length += 1
return self
# 리스트 요소를 탐색하는 과정을 보기 위한 함수
def traverse(self):
current = self.head
while(current):
print(current.val)
current = current.next
# instance method
def pop(self):
tmp = self.head
pre = tmp
if tmp is None:
return 'Undefined'
while(tmp.next):
pre = tmp
tmp = tmp.next
self.tail = pre
self.tail.next = None
self.length -= 1
if self.length == 0:
self.head = None
self.tail = None
return tmp.val
# instance method
def shift(self):
if self.head is None:
return 'Undefined'
tmp = self.head
self.head = tmp.next
self.length -= 1
if self.length == 0:
self.head = None
self.tail = None
return tmp.val
# instance method
def unshift(self, val):
newNode = Node(val)
# 리스트가 비어있는 상태
if self.head is None:
self.head = newNode
self.tail = self.head
# 리스트가 비어있지 않는 상태
# head의 next가 현재 head를 가리키게 하고
# head를 새로운 노드로 바꾼다
else:
newNode.next = self.head
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:
counter = 0
tmp = self.head
while(counter != self.index):
tmp = tmp.next
counter += 1
return tmp
# instance method
def set(self, index, val):
foundNode = self.get(index)
if foundNode:
foundNode.val = val
return True
return False
# instance method
def insert(self, index, val):
if (index < 0) or (self.length < index):
return False
if index == self.length:
return not not self.push(val)
if index == 0:
return not not self.unshift(val)
newNode = Node(val)
pre = self.get(index - 1)
tmp = pre.next
pre.next = newNode
newNode.next = tmp
self.length += 1
return True
# instance method
def remove(self, index):
if (index < 0) or (self.length <= index):
return 'Undefined'
if index == self.length - 1:
return self.pop()
if index == 0:
return self.shift()
pre = self.get(index - 1)
tmp = pre.next
pre.next = tmp.next
self.length -= 1
return tmp.val
# instance method
def reverse(self):
# 현재 다룰 요소
node = self.head
# 다음에 다룰 요소
next = None
# 이전에 다룬 요소
prev = None
# head와 tail 교환
self.head, self.tail = self.tail, self.head
for i in range(self.length):
# 다음에 다룰 요소 = 현재 노드의 .next
next = node.next
# 현재 노드의 .next = 이전에 다룬 요소
node.next = prev
# 이전에 다룬 요소 = 현재 노드
prev = node
# 현재노드 = 다음에 다룰 요소
node = next
return self
# 노드들 선언
print("---Make Node---")
L = SinglyLinkedList()
L.push('HELLO')
L.push('YOU')
L.push('GOODBYE')
L.push('!')
L.push('?')
L.push('!')
print('\n---SinglyLinkedList---')
# 노드들 출력
L.traverse()
print('\n---pop fcn---')
# pop 수행
print(L.pop())
# 리스트 길이, tail 출력
print('리스트 길이: ', L.length)
print('tail 값: ', L.tail.val)
print('\n---SinglyLinkedList---')
# 노드들 출력
L.traverse()
print('\n---shift fcn---')
# shift 수행
print(L.shift())
# 리스트 길이, head 출력
print('리스트 길이: ', L.length)
print('head 값: ', L.head.val)
print('\n---SinglyLinkedList---')
# 노드들 출력
L.traverse()
print('\n---unshift fcn---')
# unshift 수행
L.unshift("Hi")
# 리스트 길이, head 출력
print('리스트 길이: ', L.length)
print('head 값: ', L.head.val)
print('\n---SinglyLinkedList---')
# 노드들 출력
L.traverse()
print('\n---get fcn---')
# get 수행
num = 3
print('index: ', num)
print(L.get(num).val)
print('\n---set fcn---')
# set 수행
num = 3
Str = ':0'
print('index: ', num)
print('val: ', Str)
print(L.set(num, Str))
print('\n')
# set 수행
num = -1
Str = ':0'
print('index: ', num)
print('val: ', Str)
print(L.set(num, Str))
print('\n---SinglyLinkedList---')
# 노드들 출력
L.traverse()
print('\n---insert fcn---')
# insert 수행
num = 0
Str = 'WOW'
print('index: ', num)
print('val: ', Str)
print(L.insert(num, Str))
print('\n---SinglyLinkedList---')
# 노드들 출력
L.traverse()
print('\n')
# insert 수행
num = L.length
Str = 'WOW'
print('index: ', num)
print('val: ', Str)
print(L.insert(num, Str))
print('\n---SinglyLinkedList---')
# 노드들 출력
L.traverse()
print('\n')
# insert 수행
num = 3
Str = 'WOW'
print('index: ', num)
print('val: ', Str)
print(L.insert(num, Str))
print('\n---SinglyLinkedList---')
# 노드들 출력
L.traverse()
print('\n---remove fcn---')
print(L.remove(0))
print('\n---SinglyLinkedList---')
# 노드들 출력
L.traverse()
print('\n')
print(L.remove(L.length))
print(L.remove(L.length - 1))
print('\n---SinglyLinkedList---')
# 노드들 출력
L.traverse()
print('\n')
print(L.remove(3))
print('\n---SinglyLinkedList---')
# 노드들 출력
L.traverse()
print('\n---reverse fcn---')
L.reverse
print('\n---SinglyLinkedList---')
# 노드들 출력
L.traverse()
자료구조: 빅오 복잡도
- Insertion: O(1)
- Removal: it depends ... O(1) or O(N)
- Searching: O(N)
- Access: O(N)
반응형
'내 생각 > 강의' 카테고리의 다른 글
[Udemy] JavaScript 알고리즘 & 자료구조 마스터클래스_Section 21 (0) | 2023.08.08 |
---|---|
[Udemy] JavaScript 알고리즘 & 자료구조 마스터클래스_Section 20 (0) | 2023.07.27 |
[Udemy] JavaScript 알고리즘 & 자료구조 마스터클래스_Section 18 (0) | 2023.07.24 |
[EBS_위대한 수업] [경제학] 리처드 도킨스, 당신이 몰랐던 진화론_5강 과학이라는 마법 (0) | 2023.07.10 |
[EBS_위대한 수업] [경제학] 리처드 도킨스, 당신이 몰랐던 진화론_4강 불완전한 설계 (0) | 2023.07.08 |
Comments