이번 시간에는 그래프 소스에 대해 알아본다.
행렬을 이용하여 구현하는 방법과 리스트를 이용하여 구현하는 방법 2가지 인데,
먼저 행렬을 이용하여 구현한 인접 행렬 그래프를 알아본다.
그래프의 관련 내용은 검색하면 금방 알아 볼 수 있기 때문에 여기서는 설명 하지 않는다.
먼저 인접행렬그래프의 헤더파일을 살펴보자.
1. arraygraph.h
- #ifndef _ARRAYGRAPH_H_
- #define _ARRAYGRAPH_H_
- #define UNDIRECTION 0 //무방향 그래프
- #define DIRECTION 1 //방향 그래프
- #define SUCCESS 1
- #define FAIL 0
- #define USE 1
- #define NOT_USE 0
- typedef struct ArrayGraphType{
- int maxVertexCount; //최대 노드 수
- int currentVertexCount; //현재 노드 수
- int graphtype; //그래프의 타입(방향성, 무방향성)
- int **ppAdjEdge; //간선 저장 위한 2차원 배열
- int *pVertex; //노드 저장을 위한 1차원 배열
- }ArrayGraph;
- ArrayGraph* createUndirectGraph(int maxVertexCount); //무방향성 그래프 생성
- ArrayGraph* createDirectGraph(int maxVertexCount); //방향성 그래프 생성
- void deleteArrayGraph(ArrayGraph* pGraph); //그래프 제거
- int addVertexArrayGraph(ArrayGraph* pGraph, int vertexID); //노드 생성
- int removeVertexArrayGraph(ArrayGraph* pGraph, int removeID); //노드 삭제
- int addEdgeArrayGraph(ArrayGraph* pGraph, int fromID, int toID, int weight); //간선 생성
- int removeEdgeArrayGraph(ArrayGraph* pGraph, int fromID, int toID); //간선 제거
- void displayArrayGraph(ArrayGraph* pGraph); //그래프 출력
- #endif
- ArrayGraph* createUndirectGraph(int maxVertexCount)
- {
- ArrayGraph *pReturn = NULL;
- int i,j;
- //노드 갯수 에러 검사
- if(maxVertexCount <= 0)
- {
- return NULL;
- }
- //그래프 구조체 동적할당
- //동적할당 에러 검사
- if(pReturn==NULL)
- {
- return NULL;
- }
- pReturn->maxVertexCount=maxVertexCount; //최대 노드 개수 입력
- pReturn->currentVertexCount=0; //현재 노드 개수 0 입력
- pReturn->graphtype = UNDIRECTION; //무방향성 그래프
- //최대 노드 개수만큼 동적할당
- //동적할당 에러 검사
- if(pReturn->pVertex==NULL)
- {
- return NULL;
- }
- //최대 노드 개수만큼 필요한 간선 수 동적할당
- //동적할당 에러 검사
- if(pReturn->ppAdjEdge==NULL)
- {
- return NULL;
- }
- //최대 노드 수 만큼 간선의 데이터 입력할 공간 할당
- for(i=0;i<maxVertexCount;i++)
- {
- //pReturn->ppAdjEdge[i]의 메모리 할당 실패 예외 처리
- if(pReturn->ppAdjEdge[i]==NULL)
- {
- for(j=0;j<i-1;j++)
- //남은 메모리 전체 해제
- return NULL;
- }
- }
- //그래프의 노드 초기화
- for(i=0;i<maxVertexCount;i++)
- return pReturn;
- }
2) ArrayGraph* createDirectGraph(int maxVertexCount)
아래 함수는 방향성그래프 생성을 위한 그래프이다. 내부를 확인하면, 일단 무방향성 그래프를 생성하고,
거기서 반환된 그래프 구조체의 데이터 중 그래프 타입을 방향성으로 변경하여 반환한다.
- ArrayGraph* createDirectGraph(int maxVertexCount)
- {
- ArrayGraph* pReturn = createUndirectGraph(maxVertexCount);
- if(pReturn==NULL)
- return NULL;
- pReturn->graphtype = DIRECTION;
- return pReturn;
- }
3) void deleteArrayGraph(ArrayGraph* pGraph)
생성한 인접행렬그래프를 제거하기 위한 코드이다.
- void deleteArrayGraph(ArrayGraph* pGraph)
- {
- int i,j;
- if(pGraph == NULL)
- return;
- for(i=0;i<pGraph->maxVertexCount;i++)
- {
- if(pGraph->ppAdjEdge[i]!=NULL)
- {
- }
- }
- }
4) int addVertexArrayGraph(ArrayGraph* pGraph, int vertexID);
노드를 추가하는 기능을 하는 함수이다. 그래프 구조체 포인터와, 추가할 노드의 인덱스를 입력한다.
그래프 구조체 포인터의 상태, 최대노드갯수, 추가하고픈 노드가 이미 있는지 등을 확인하고 생성한다.
- int addVertexArrayGraph(ArrayGraph* pGraph, int vertexID)
- {
- if(pGraph==NULL)
- {
- return FAIL;
- }
- if(vertexID>pGraph->maxVertexCount)
- return FAIL;
- if(pGraph->pVertex[vertexID]==USE)
- return FAIL;
- pGraph->pVertex[vertexID] = USE;
- pGraph->currentVertexCount++;
- return SUCCESS;
- }
5) int removeVertexArrayGraph(ArrayGraph* pGraph, int removeID)
-원하는 노드를 제거하기 위한 함수이다. 이 때 주의해야할 점은 노드 뿐만 아니라, 노드에 연결된
모든 간선도 제거해야 한다는 것이다. 아래 빨간색으로 표현된 코드 부분이다.
- int removeVertexArrayGraph(ArrayGraph* pGraph, int removeID)
- {
- int i;
- if(pGraph==NULL)
- return FAIL;
- if(pGraph->pVertex[removeID]==NOT_USE)
- return FAIL;
- if(removeID>pGraph->maxVertexCount)
- return FAIL;
- for(i=0;i<pGraph->maxVertexCount;i++)
- {
- removeEdgeArrayGraph(pGraph, removeID, i);
- removeEdgeArrayGraph(pGraph, i, removeID);
- }
- pGraph->pVertex[removeID] = NOT_USE;
- pGraph->currentVertexCount--;
- return SUCCESS;
- }
6) int addEdgeArrayGraph(ArrayGraph* pGraph, int fromID, int toID, int weight);
- 간선을 추가하는 함수
간선 생성을 원하는 노드에서 노드까지를 입력하고, 가중치를 입력한다.
그리고 그래프가 무방향성이라면 대칭되는 간선도 동일한 값을 입력하여 준다.
- int addEdgeArrayGraph(ArrayGraph* pGraph, int fromID, int toID, int weight)
- {
- if(pGraph==NULL)
- return FAIL;
- if(fromID>pGraph->maxVertexCount || toID>pGraph->maxVertexCount)
- return FAIL;
- if(pGraph->pVertex[fromID]==NOT_USE||pGraph->pVertex[toID]==NOT_USE)
- return FAIL;
- if( weight<=0)
- return FAIL;
- pGraph->ppAdjEdge[fromID][toID] = weight;
- if(pGraph->graphtype==UNDIRECTION)
- pGraph->ppAdjEdge[toID][fromID] = weight;
- }
7) int removeEdgeArrayGraph(ArrayGraph* pGraph, int fromID, int toID);
-간선을 제거하기 위한 함수.
간선 제거를 위해 가중치를 0으로 초기화 하고, 무방향성이라면 동일하게 대칭되는 곳 또한 0으로 초기화!
- int removeEdgeArrayGraph(ArrayGraph* pGraph, int fromID, int toID)
- {
- if(pGraph==NULL)
- return FAIL;
- if(fromID>pGraph->maxVertexCount || toID>pGraph->maxVertexCount)
- return FAIL;
- if(pGraph->pVertex[fromID]==NOT_USE||pGraph->pVertex[toID]==NOT_USE)
- return FAIL;
- pGraph->ppAdjEdge[fromID][toID] = 0;
- if(pGraph->graphtype==UNDIRECTION)
- pGraph->ppAdjEdge[toID][fromID] = 0;
- return SUCCESS;
- }
8) void displayArrayGraph(ArrayGraph* pGraph)
-현재 그래프 상태를 출력하는 함수
void displayArrayGraph(ArrayGraph* pGraph)
{
int i,j;
if(pGraph==NULL)
return;
if(pGraph->graphtype==UNDIRECTION) printf("Graph : UNDIRECTION\n");
if(pGraph->graphtype==DIRECTION) printf("Graph : DIRECTION\n");
for(i=0;i<pGraph->maxVertexCount;i++)
{
for(j=0;j<pGraph->maxVertexCount;j++)
printf("%d ", pGraph->ppAdjEdge[i][j]);
printf("\n");
}
}
자, 그럼 위의 코드를 이용하여 테스트를 하여 보자.
아래는 예제소스이다.
- #include<stdio.h>
- #include "arraygraph.h"
- int main()
- {
- ArrayGraph* pGraph = createUndirectGraph(6);
- int i;
- for(i=0;i<6;i++)
- addVertexArrayGraph(pGraph, i);
- addEdgeArrayGraph(pGraph, 0, 3, 1);
- addEdgeArrayGraph(pGraph, 1, 3, 1);
- addEdgeArrayGraph(pGraph, 2, 3, 2);
- addEdgeArrayGraph(pGraph, 5, 2, 5);
- addEdgeArrayGraph(pGraph, 0, 1, 4);
- addEdgeArrayGraph(pGraph, 1, 3, 2);
- addEdgeArrayGraph(pGraph, 4, 5, 7);
- addEdgeArrayGraph(pGraph, 5, 2, 2);
- addEdgeArrayGraph(pGraph, 3, 3, 1);
- addEdgeArrayGraph(pGraph, 4, 1, 7);
- addEdgeArrayGraph(pGraph, 2, 1, 4);
- displayArrayGraph(pGraph);
- deleteArrayGraph(pGraph);
- }
결과는 아래와 같다!! 확인하여 보자.
위의 소스들이 정확히 올바른 소스라고는 할 수 없다. 하지만 어느 정도 참고는 할 수 있길 !!!
다음 시간에는 인접리스트를 이용하여 구현하여 보자. 검증 또한 여러분의 몫!
야밤에 짧은 시간내에 코딩하려니 힘드네요....
기본 소스는 공유하겠습니다 !
'ETC > Data Struct | Algorithm' 카테고리의 다른 글
Geometry (0) | 2017.07.17 |
---|---|
[STL] algorithm 내부 sort 함수의 원형 (0) | 2015.04.01 |
이진 탐색 ( Binary Search ) (0) | 2014.05.15 |
순차 검색 (Sequential Search) (0) | 2014.05.15 |
이진트리 순회 (0) | 2013.05.01 |