티스토리 뷰


1. 개요



[그림 1] 인접행렬로 나타낸 그래프




그래프 자료구조를 나타내는 방법으로 두 가지가 있다. 하나는 인접 행렬 (adjacent Matrix) 이고 하나는 인접 리스트 (adjacent List)법이있다. 이번 글에서는 인접행렬로 그래프를 나타내는 방법을 알아보겠다.


인접행렬법은 배열로 그래프를 나타내는 것이므로 밀집그래프 (완전그래프)를 표현하는데 적절하다. 2차원 배열 특성상 한번에 메모리를 잡아햐 하기때문에 빈 공간이 생기면 메모리 낭비가 생기므로 밀집그래프를 표현하는데 있어 좋은 방법이다.


(※무방향 그래프를 표현 시 대칭성을 고려해야 한다.)






2. 그래프 구현



1. 구조체 및 함수 선언 
 

extern 전역 변수로 방문처리를 확인 할 1차원 배열을 하나 선언해준다. ( 0번방 -> A ,  1번방 -> B... 이런 식)
구조체에는 인접행렬을 표기할 배열 graph 2차원 배열, 정점의 갯수와 간선의 갯수를 저장해줄 int형 변수들을 선언해준다.

 2. 그래프 초기화 

이 글에서는 행렬 텍스트 파일을 파일입출력을 통해 불러와 반복문을 통해 배열에 입력하는 방식으로 구현했다.
FILE 함수를 통해 파일을 읽어들인 후, 간선, 정점의 갯수를 모두 읽는다.

우선, 인접행렬영역을 0 (방문X)로 초기화를 해주고, 무방향 그래프에서의 대칭성을 고려하여 간선의 갯수만큼 반복문을 이용해 행렬에 입력한다.

 3. 그래프 출력
 




3. 깊이우선탐색 ( DFS )



[그림 2] 깊이우선탐색 순서



그래프내의 각 정점들을 간선을 타고 중복없이 한 번씩 방문하는 방법으로 깊이 우선 탐색 ( Depth First Search ) 법과 너비 우선 탐색 ( Breadth First Search)법이 있다. 무방향 그래프는 특성상 방향이 없기때문에 순회 순서가 유일하지 않다는 특징이 있다.

2가지 중 하나인 "깊이 우선 탐색(DFS)" 는 탐색을 시작할 정점에 연결된 정점 중 하나를 선택하여 들어가고 그 하나와 연결된 정점들 중 또 하나를 선택해서 들어가고 깊이 들어가는 방식으로 탐색하는 기법이다.


DFS의 과정은 스택을 사용하므로 재귀와 비재귀로 구현 할 수 있다. 



< 재귀법 >


 4. 깊이우선탐색 (DFS) 메인
  

초기에 선언했던 extern 변수 check 배열을 모두 0으로 초기화 시킨다. 그리고 나서 정점의 갯수만큼 반복문을 돌려 ( 0번방 'A' 부터 시작한다고 가정 ) 방문배열이 0일 경우 DFS 함수를 호출하여 구덩이 ( 탐색 ) 를 판다.

 5. 깊이우선탐색 (DFS) 재귀
 

전달인자로 받은 정점번호를 방문처리 해준 뒤, ( 1로 바꿈 ) 그 정점을 visit함수 ( 출력 ) 한다.
다음으로, 정점갯수만큼 반복문을 설정.. 해당 정점에 연결된 정점이 있고 그 정점이 방문배열에서 방문한 적이 없는 정점 이라면 재귀호출을 통해 정점 방문 처리를 해준다.



< 비재귀 >


 6. 깊이우선탐색 (DFS) 비재귀
  

재귀기법을 사용하지 않으면 스택자료구조를 이용해야한다. 스택 초기화 및 생성을 하고 재귀방법과 똑같이 체크배열은 0으로 시켜준다.
순차적으로 정점을 방문한다. 그 정점이 방문한경우가 아니라면 스택에 그 정점을 푸쉬하고 방문상태를 바꿔준다 ( 1로 ) 그리고 스택이 모두 비면 한 연결 요소에 대해 순회가 끝난것을 의미하므로 스택이 빌 때까지 반복문을 걸어준다.
pop을 하여 정점을 꺼내고 해당 정점에 연결된 정점이 있고 방문처리 되지 않은 경우 그 인접정점을 스택에 넣고 방문처리를 해준다.
이런 과정을 모두 하고나면 모든 정점에 대해 순회가 완료된다.




4. 너비우선탐색 ( BFS )





[그림 3] 너비우선탐색 순서


너비우선탐색 (BFS) 는 시작한 정점과 연결된 모든 정점을 탐색하고 다시 시작 정점의 다른 연결된 정점을 찾는 순으로, 깊이 들어가기전에 옆으로 넓게 퍼지며 탐색하는 기법이다. DFS와 달리 너비우선탐색 (BFS) 는 스택을 사용하지않고 큐 자료구조를 이용해야 한다. 따라서 재귀호출기법으로는 구현할 수 없다.



 7. 너비우선탐색 (BFS)
 

과정은 DFS랑 매우 비슷하다. 자료구조만 스택에서 큐로 바꾸면 바로 너비우선탐색법이 된다.

큐를 선언 및 초기화 후 체크배열을 초기화한다. 그리고 시작 정점을 기준으로 하여 큐에 넣고 큐가 빌때까지 반복문, 인접정점, 방문 유무를 판단한다.
[그림 3] 을 예로들어서 설명하면 "1"을 시작으로 Enqueue한뒤, "1"의 인접정점 8 , 5, 2 를 순서대로 모두 Enqueue한다. 그리고 Dequeue를 하면 큐 특성상 첫번째로 넣은 값이 나오게 되므로 8을 방문처리하고 8의 인접정점 6 ,4 ,3 을 모두 Enqueue 그 다음 5를 Dequeue... 5는 인접정점이 없으므로 다음 Dequeue 2를 방문...이런 식으로 옆으로 넓게 퍼지며 탐색을 한다.




번외로 그래프 내의 연결 요소별로 정점들을 출력하고 연결 요소의 개수를 리턴하는 함수를 구현해보았다.


 8. 그래프 연결 요소 출력
 



'프로그래밍 > 자료구조' 카테고리의 다른 글

5. 그래프 (Graph) - 인접리스트법  (0) 2016.08.23
4. 이진 트리 (Binary Tree)  (0) 2016.08.23
3. 원형 큐 (Circular Queue)  (0) 2016.08.22
2. 스택 (Stack)  (0) 2016.08.22
1. 링크드 리스트 (Linked List)  (0) 2016.08.22
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
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
글 보관함