그래프는 기본적으로 모든 sns에서 사용된다. (넷플릭스의 영화 추천, 광고주가 무언가를 기반으로 대상을 정할 때)
트리의 경우에, 노드가 한 개의 부모,즉 가장 위에 있는 노드를 가졌다. 거기서부터 내려오는 자식 노드가 여러개 있었다.트리는 그래프의 일종이다.
실제 그래프를 코딩하고, 저장하고, 코드로 표현하는 방법을 간단하게 보자
실제로 그래프를 저장할 때 중요한 정보는 노드, 즉 실제 정점들과 연결을 저장하는 방식이다. 예를 들어, 연결리스트에서는 next와 previous를 했다. 이진 탐색 트리에서는 left와 right가 클래스에 있었다. 그러나 이것들은 그래프에 쓸 수 없다. 왜? 노드의 개수나 노드 사이의 연결인 간선의 개수가 정해져 있지 않기 때문이다.
우리가 살펴볼 접근법은 두가지
행과 렬이 있는 것
출처 : 유데미 js알고리즘&자료구조 마스터클래스 강의
무방향그래프는 인접행렬이 대칭구조일 수 밖에 없다. 양방향이기 때문에
방향 그래프는 대칭 구조가 아니다.
근데 만약 각 노드가 숫자가 아니거나, 숫자여도 큰 차이가 나면 배열을 사용하지 말아야 할까?
=> 해시 테이블을 사용하자 키-값 데이터 구조
딕셔너리나, 자바스크립트에서는 객체나 맵이 있다.
출처 : 유데미 js알고리즘&자료구조 마스터클래스 강의
출처 : 유데미 js알고리즘&자료구조 마스터클래스 강의
인접행렬은 2차원 배열이니, 새로운 정점을 추가하면 한 칸을 더하는 것이 아니라 두칸을 더한다. 따라서 O(V^2)
인접행렬에서 데이터가 퍼져있고, 연결 즉 간선이 많지 않으면 행렬을 사용하지 않는 것이 낫다.
왜?
그래프에 대한 기본 클래스는 아주 기본적인 것
우리는 무방향 그래프 클래스를 작성할 것이다. 왜냐? 무방향 그래프를 간선이 한 방향으로만 연결되는 방향 그래프로 바꾸는 것은 아주 간단하기 때문~
간선을 만들기 전에 먼저 정점을 만들어줘야 한다.
class Graph {
constructor(){
this.adjacencyList ={}
}
만약 g라는 그래프에 addVertex함수를 이용해 Tokyo 라는 vertex를 추가해주는거
g.addVertex("Tokyo") => { "Tokyo" : []}
class Graph{
constructor(){
this.adjaceneyList = {}
}
addVertex(vertex){
if(!this.adjaceneyList[vertex]) this.adjaceneyList[vertex] = [];
}
}
Tokyo, Dallas, Los Angeles, Hong Kong, 이런식으로 도시들 추가
항공편 관련 작업을 하고 있는 것! 항공잡지 뒤에 나와있는 모든 항공편과 연결된 비행편을 표현하는 것을 목표로 작업을 하고 있는 것
{
"Tokyo" : [],
"Dallas" : [],
"Aspen" : []
}
=>
g.addEdge("Tokyo", "Dallas")
=>
{
"Tokyo" : [Dallas],
"Dallas" : [Tokyo],
"Aspen" : []
}
class Graph{
constructor(){
this.adjaceneyList = {}
}
addVertex(vertex){
if(!this.adjaceneyList[vertex]) this.adjaceneyList[vertex] = [];
}
addEdge(v1, v2){
this.adjaceneyList[v1].push(v2);
this.adjaceneyList[v2].push(v1);
}
}
예상)
{
"Tokyo": [Dallas],
"Dallas" : ["Tokyo", "Aspen"],
"Aspen" : ["Dallas"]
}
=> g.removeEdge("Tokyo","Dallas")
=> {
"Tokyo": [],
"Dallas" : ["Aspen"],
"Aspen" : ["Dallas"]
}
class Graph{
constructor(){
this.adjacencyList = {}
}
addVertex(vertex){
if(!this.adjacencyList[vertex]) this.adjaceneyList[vertex] = [];
}
addEdge(v1, v2){
this.adjacencyList[v1].push(v2);
this.adjacencyList[v2].push(v1);
}
removeEdge(vertex1,vertex2){
this.adjacencyList[vertex1] = this.adjacencyList[vertex1].filter(v => v !== vertex2 )
this.adjacencyList[vertex2] = this.adjacencyList[vertex2].filter(v => v !== vertex1 )
}
}
class Graph{
constructor(){
this.adjacencyList = {}
}
addVertex(vertex){
if(!this.adjacencyList[vertex]) this.adjaceneyList[vertex] = [];
}
addEdge(v1, v2){
this.adjacencyList[v1].push(v2);
this.adjacencyList[v2].push(v1);
}
removeEdge(vertex1,vertex2){
this.adjacencyList[vertex1] = this.adjacencyList[vertex1].filter(v => v !== vertex2 )
this.adjacencyList[vertex2] = this.adjacencyList[vertex2].filter(v => v !== vertex1 )
}
removeVertex(vertex){
while(this.adjacencyList[vertex].length){ // 홍콩 배열길이 만큼
const adjacentVertex = this.adjacencyList[vertex].pop();//뒤에서부터 없애고 할당한다.
this.removeEdge(vertex, adjacentVertex); // 할당된 나라에 가서 홍콩 간선을 제거한다.
} // 관련 간선들 삭제하는거
delete this.adjacencyList[vertex] //그 정점 삭제하는거
}
}