내 생각/강의
[Udemy] JavaScript 알고리즘 & 자료구조 마스터클래스_Section 26
호랑구야
2023. 9. 27. 09:00
* 수업은 JS 기반이지만 Python으로 구현
Section 26
그래프 소개
- 그래프란 유한한고 변할 수 있는 꼭지점/노드/점들의 집합으로 구성된 데이터 구조이다.
- 꼭지접들의 집합에 순서가 없는 경우 무방향 그래프, 순서가 있는 경우 유방향 그래프라고 한다.
그래프 사용하는 경우
- SNS
- 지도의 방향 안내, 위치, 길 찾기
- 추천 알고리즘
- 라우팅, 사이트를 요청하고 전체 네트워크에 퍼져있는 것 중 일부 연결 부위를 주는 것
그래프 유형
- vertex: node
- edge: node들 사이의 연결
- 무방향 그래프: edge에 방향이 없는 그래프
- 유방향 그래프: edge에 방향이 있는 그래프
- 가중 그래프: edge에 부여된 값이 있는 그래프
- 비가중 그래프: edge에 부여된 값이 없는 그래프
그래프 정렬
- 인접 행렬
- 보통 중첩 행렬을 이용하여 boolean 값을 활용한다. 두 개의 노드(각 행과 열의 값)에 연결이 있다면 1, 없다면 0으로 표시한다.
- 공간을 더 차지한다.
- 퍼져있는 데이터를 다룰 때 좋지 않다.
- 모든 edge를 루프를 돌아 확인할 때 더 느리다.
- 특정 edge를 확인하는데에 빠르다.
- 인접 리스트
- 인덱스가 노드의 값인데, 그 노드에 연결된 노드의 숫자값을 리스트로 가진다.
- 만약 노드의 값이 숫자가 아니거나 순서를 갖지 않는 경우, 문자이거나 숫자 사이에 큰 차이가 있는 경우에는 해시 테이블을 활용한다.
- 공간을 덜 차지한다.
- 모든 edge를 루프를 돌아 확인할 때 더 빠르다.
- 특정 edge를 확인하는데에 느릴 수 있다.
- 인접 행렬과 인접 리스트의 Big O
- |V|: vertices의 숫자
- |E|: edges의 숫자
동작 | 인접 리스트 | 인접행렬 |
add Vertex | O(1) | O(|V^2|) |
add Edge | O(1) | O(1) |
remove Vertex | O(|V|+|E|) | O(|V^2|) |
remove Edge | O(|E|) | O(1) |
query | O(|V|+|E|) | O(1) |
storage | O(|V|+|E|) | O(|V^2|) |
class 소개
- vertex 사이의 연결, edge를 저장할 adjacencyList라는 속성을 선언한다.
addVertex method 소개
- 추가할 vertex를 입력받는 함수를 만든다.
- 정점의 이름을 인접 리스트에 key로 추가하며, value는 빈 배열로 한다.
addEdge method 소개
- vertex1, vertex2를 입력받는 함수를 만든다.
- 인접 리스트에 vertex1 키를 찾아서 vertex2를 그 배열에 넣어주어야 한다.
- 인접 리스트에 vertex2 키를 찾아서 vertex1을 그 배열에 넣어주어야 한다.
removeEdge method 소개
- vertex1, vertex2를 입력받는 함수를 만든다.
- 인접 리스트에 vertex1 키를 찾아서 vertex2를 그 배열에서 제거해야 한다.
- 인접 리스트에 vertex2 키를 찾아서 vertex1을 그 배열에서 제거해야 한다.
removeVertex method 소개
- 제거할 vertex를 입력받는 함수를 만든다.
- 인접 리스트에 제거할 vertex가 있는 다른 vertex가 있는지 확인하기 위해 모든 로프를 돌아야 한다.
- 루프 내에서 removeEdge 함수를 이용해 제거하고 싶은 vertex와 관련된 모든 edge를 제거해야 한다.
- 인접 리스트에 있는 제거하고 싶은 vertex의 키를 삭제해야 한다.
method 구현
class Graph:
#constructor
def __init__(self):
self.adjacencyList = {}
def addVertex(self, v):
if not v in self.adjacencyList:
self.adjacencyList[v] = []
def addEdge(self, v1, v2):
self.adjacencyList[v1].append(v2)
self.adjacencyList[v2].append(v1)
def removeEdge(self, v1, v2):
self.adjacencyList[v1] = list(filter(lambda x: x != v2, self.adjacencyList[v1]))
self.adjacencyList[v2] = list(filter(lambda x: x != v1, self.adjacencyList[v2]))
def removeVertex(self, v):
while(len(self.adjacencyList[v])):
adjacentV = self.adjacencyList[v].pop()
self.removeEdge(v, adjacentV)
del self.adjacencyList[v]
# addVertex, addEdge, 아래 두 결과가 같은지 확인
# 1
g = Graph()
g.addVertex("Tokyo")
g.addVertex("Dallas")
g.addVertex("Aspen")
g.addEdge("Tokyo", "Dallas")
g.adjacencyList
# 2
g = Graph()
g.addVertex("Tokyo")
g.addVertex("Dallas")
g.addVertex("Aspen")
g.addEdge("Dallas", "Tokyo")
g.adjacencyList
# removeVertex, removeEdge 확인
g = Graph()
g.addVertex("Dallas")
g.addVertex("Tokyo")
g.addVertex("Aspen")
g.addVertex("Los Angeles")
g.addVertex("Hong Kong")
g.addEdge("Dallas", "Tokyo")
g.addEdge("Dallas", "Aspen")
g.addEdge("Hong Kong", "Tokyo")
g.addEdge("Hong Kong", "Dallas")
g.addEdge("Los Angeles", "Hong Kong")
g.addEdge("Los Angeles", "Aspen")
g.adjacencyList
g.removeVertex("Hong Kong")
g.adjacencyList
반응형