컴퓨터 과학에서 이야기하는 그래프는 일반적으로 내가 알고있는 그래프랑 달랐다. 그 주주죽 선이 그어지는 그래프가 아니라, 점끼리 이어져있는 복잡한 네트워크 망과 같은 이미지다.
그래프는 여러 개의 점들이 서로 복잡하게 연결되어 있는 관계를 표현한 자료구조다. 서로 다른 점들이 직접적인 관계를 가지고 있다면 바로 이어주는 선이 존재하고, 간접적인 관계를 가지고 있다면 다른 여러 점을 거쳐서 이어지는 선이 존재할 수 있다. 여기서 이야기하는 점은 그래프에서는 정점(vertex)라고 표현하고, 선은 간선(edge)라고 표현한다.
쉽게 말하면 그래프라는 것은 연관된 데이터들을 이어서 관계를 가지고 있는 정보를 나타낼 수 있는 자료구조다.
우리가 매일같이 그래프라는 자료구조를 사용하고 있는데, 이건 단순히 데이터 구조로만 생각하면 어렵다. 예를 들어보면 포털 사이트의 검색엔진, SNS, 네비게이션(길찾기) 등에서 사용되는 자료구조가 바로 그래프다. 여기서 더 나아가면, 넷플릭스 추천시스템이나 유사데이터를 보여주는 연관검색어까지도 적용될 수 있다. 물론 거기에는 추가적으로 데이터 보정이 들어가겠지만, 가장 핵심적인 내용은 '그래프'일 것이다.
서울에 사는 A는 부산에 사는 B와 오랜 친구 사이입니다. 이번 주말에 B의 결혼식이 있다고 하여 A는 차를 몰고 부산으로 가려고 합니다. 마침, 대전에 살고 있는 A와 B의 친구 C도 참석을 한다고 하여 A는 대전에서 C를 태워 부산으로 이동을 하려고 합니다.
위는 네비게이션이 구현되는 방식을 가지고 길을 찾는 이야기를 꺼내보았다. 위의 예제에는 3개의 정점이 존재하는데, 각각 A, B, C가 사는 도시들을 각각의 그래프 정점(vertex)로 대입할 수 있다. 그리고 이 3개의 정점은 서로 이어지는 간선(관계)를 가지고 있다.
비가중치 그래프
라고 한다.let isConnected = { seoul: { busan: true, daejeon: true }, daejeon: { seoul: true, busan: true }, busan: { seoul: true, daejeon: true } } console.log(isConnected.seoul.daejeon) // true console.log(isConnected.daejeon.busan) // true
코드로 나타내면 다음과 같다. 하지만 지금의 정보로는 연결되어있는지 안되어있는지에 대한 정보만 있기때문에 네비게이션의 기능을 할 수 있도록 자료구조를 수정한다면 거리나 방향을 표시해서 가중치 그래프로 표현할 수 있다. 그렇게 함으로서 비로소 관계성을 가지고 있는 가중치 그래프
가 될 수 있다.
추가적으로 이야기한 SNS의 경우, 무향그래프의 경우에는 페이스북의 친구관계(양방향 관계성)와 유향그래프의 경우에는 인스타그램의 팔로우관계(일방향 관계성)을 예를 들 수 있다. 넷플릭스나 왓챠플레이의 추천시스템은 아마도 A유저가 좋아하는 목록들과 B유저가 좋아하는 목록을 엮어서 서로에게 연관된 영화를 추천할 수 있는 방식으로 되어있을 것이기 때문에 일종의 그래프 데이터일 것이라고 추측한다.(나중에 알게되겠지만..)
앞서 그래프의 관계성을 보면 간선이 연결되어있는 것으로 표현을 했는데, 이것을 인접한다라고 이야기한다. 인접 행렬은 정점들끼리 인접하고 있는 정보를 알려주는 행렬으로 2차원 배열의 모습을 가지고 있다. 무향 그래프의 경우 행과 열에 모두 1로 표시가 되고, 유향그래프의 경우 행(from) 렬(to)에서 to 방향에 1이 있게 된다. 만약에 관계성이 있는 가중치 그래프
라고하면 굳이 1이라는 연결 표시가 아니라 거리
값 그자체가 할당되어있을 수 있다.
인접행렬의 한 행을 가져다 놓은 것이라고 보면 편하다. 그냥 어디에 연결되어있는지를 빠르게 확인하기 위한 정보다. 만약에 정점별로 우선 순위가 있다면 우선 순위별로 정렬해서 담아서 사용하면된다. 만약 없다면 그냥 리스트를 그대로 가져다 쓰면 된다.
트리구조는 그래프의 여러 구조중에 일방향 그래프의 한 종류다. 따지고 보면 그냥 그래프인데 밑으로만 뻗어나가는 것이다. 생성되는 모양이 거꾸로된 나무와 비슷해서 트리구조라고 부른다. Tree Tree Tree
일종의 가계도 처럼 생겼는데, 데이터가 바로 아래에 있는 하나 이상의 데이터에 단방향으로 연결되는 계층적 자료구조라고 할 수 있다. 내가 사용하고 있는 맥의 파일시스템 역시 이러한 트리구조로 이루어져있다. 데이터를 순차적으로 나열시킨 형태인 선형구조가 아닌, 하나의 데이터 뒤에 여러개의 데이터가 존재할 수 있는 비선형 구조로 되어 있고, 계층적으로 표현이 되며 아래로만 뻗기 때문에 사이클이 없다.(밑으로만 간다.)
Root
: 루트는 꼭대기에 있는 꼭짓점 데이터다. 여러개의 간선으로 데이터를 연결한다.
Node
: 각 데이터가 매달려 있는 정점(vertex)
상위노드와 하위노드
: 위에 달린놈이 부모 노드, 아래달린놈이 자식 노드
자식없는 노드
: 리프 노드!!!!!
동일한 깊이의 노드들
:형제자매 노드!
Height(높이)
: 루트부터 가장 안쪽에 있는 노드까지의 레벨
Depth(깊이)
: 특정노드부터 루트까지의 레벨
트리 일부를 떼오면 Subtree(서브트리)
라고 부른다.
언뜻 보아도 눈에 익숙한 이 자료구조의 형태는 구조를 표현하는 데에 초점이 맞춰져 있기 때문에 주변에서 알게 모르게 많이 접했다. 사람이 사용하기 편리하기 위해, 쓰기 좋기 위해 만들어진 자료구조이기 때문이다.
가장 대표적으로, 컴퓨터의 디렉토리 구조를 생각할 수 있다. 어떠한 프로그램이나 파일을 찾을 때 우리는 우리만의 방식으로 잘 정돈된 폴더에서 타고 들어가 원하는 것을 찾게 된다. 혹은, 이미 만들어 놓은 폴더 구조(예시로, C:/kimcoding/document/따오기/참새)에서 찾고는 한다. 모두 하나의 폴더에서 시작되어, 가지처럼 뻗어나가는 형태를 보이고 있다.
자료구조중에 제일 어려웠던 그래프를 정리했다. 이 부분에서 명확하지 않은 부분이 많아서 헷갈렸는데 관계성과 순서와 관련된 정보를 담고있다는 식으로 이해하면 좀 빠를 듯 하다.