본문 바로가기

알고리즘

인접행렬을 이용한 그래프 구현하기(알고리즘_교보문고_국형준 참고)

후기


오류 지점 : E를 초기화 시키지 않아서 밑에 표시된 오류지점 바로 전 for구문이 다돌아서 E[21]인덱스에 접근 해버렸음
그것이 V에 있는 정보를 바꿔버렸음. 구조체상으로 보면 E[0]~E[20]존재하고 E[21]은 없는데 이게 그 다음에 있는 V 메모리에 접근한 것
(근데 항상 이렇게 두 메모리가 인접해서 할당되진 않을 수 있다고 함.)



#디버깅 할 때 팁 얻음


F5 디버깅 모드 시작 및 중단점까지 실행
   디버깅 모드 시작 된다음에 디버그 탭에서 창을 보면 조사식이 있음(조사식으로 변수값 점검)
  
F9 중단점 설정
F10 한줄씩(?) 실행



설계 노트







-작성된 코드



#include
#include

typedef struct Edge{

	int endV1;
	int endV2;
	int w;

}EDGE;


// 이거 구조에 대해서 생각할 필요가 있음. 일단은 포인터 형식을 이용하지 않았음
typedef struct Graph{

	EDGE E[21];
	int V[7] ;
	int Mat[7][7];

}GRAPH;


void aboutNode(GRAPH* G, int node);
void modifyEdge(GRAPH* g, int v1, int v2, int w);

void main()
{
	GRAPH *G = (GRAPH*)malloc(sizeof(GRAPH));
	// 그래프 초기화
	int i , j ;

	for(i=0; i< 7; i++)            //sizeof(G->V)/sizeof(int) 쓰면되는데 보기 편하게 그냥 7씀
	{
		G->V[i] = i;
	}

	for(i=0; i<7 ; i++)
	{
		for(j=0; j<7; j++)
		{
			G->Mat[i][j] = -1;         // Mat[0][?] 꼴이나 Mat[?][0] 꼴들은 아예 안쓸거라 -1말고 다른 -값으로 초기화 하는 것도 좋음. 여기선 필요 x
		}
	}
	// 초기화 안해서 오류발생 유도
	for(i=0; i<21;i++){
		G->E[i].endV1 = 0;
		G->E[i].endV1 = 0;
		G->E[i].w = 0;
	}

	char st = NULL;
	int k;
	int a,b, w;

	while(st!= 'q')
	{
		scanf("%c", &st);
		switch (st)
		{
		case 'a':
			scanf("%d" , &k);
			aboutNode(G, k);
			break;
		case 'm':
			scanf("%d %d %d", &a,&b,&w);
			modifyEdge(G, a,b,w);
			break;
		case 'q':
			break;
		}
	}


}


void aboutNode(GRAPH* G, int node)
{
	// 노드 존재여부 확인
	//printf("%d\n", node); //test
	int i , x;

	for(i=1; iV)/sizeof(int) ; i++)
	{
		//printf("%d\n", i); //test
		if(G->V[i] == node)       // if(G->V[i] == node) 조건 왜 안먹히지
			break;
	}
	if(i == sizeof(G->V)/sizeof(int)){
		printf("-1\n");
		return;
	}

	// 인접한 정점과 그것에 도달하는 간선의 가중치 출력
	int ei;  //edgeIndex;

	for(i=1; iV)/sizeof(int) ; i++)
	{	
		if(G->Mat[node][i] != -1)
		{
			printf(" %d", i);      //인덱스랑 해당 인덱스에 들어있는 값이 같아서 i로 출력했지만 다른 경우에 문제가 될 수 있음
			ei = G->Mat[node][i];
			printf(" %d", G->E[ei].w);      // ->와 . 이 정확성 착각할 수 있음 
		}
	}
	printf("\n");
}


void modifyEdge(GRAPH* g, int v1, int v2, int w)
{
	int i;

	//노드1 존재하는 노드인지 확인
	for(i=1; iV)/sizeof(int) ; i++)
	{
		if(g->V[i] == v1)
			break;
	}
	if(i == sizeof(g->V)/sizeof(int)){
		printf("-1\n");
		return;
	}
	//노드 2  "
	for(i=1; iV)/sizeof(int) ; i++)
	{
		if(g->V[i] == v2)
			break;
	}
	if(i == sizeof(g->V)/sizeof(int)){
		printf("-1\n");
		return;
	}
	// 둘사이에 간선이 없음 --> 간선 생성
	if(g->Mat[v1][v2] == -1)
	{
		//간선에 대한 정보를 넣을 위치 찾기
		for(i=0; i<21; i++)
		{
			if(g->E[i].w == 0)
				break;
		} 
		//****************오류발생지점

		//해당 간선에 대한 정보를 업데이트
		g->E[i].endV1 = v1; 
		g->E[i].endV2 = v2;
		g->E[i].w = w;
		
		//간선과 관련이 있기 때문에 행렬부분도 업데이트
		g->Mat[v1][v2] = i;
		g->Mat[v2][v1] = i;

		return;
	}
	//둘 사이에 간선이 있는 경우 -> 또 2개로 나뉨  1. 입력된 w=0이라서 제거 하는 경우 2. w !=0 이라서 수정하는 경우 
	int e_index = g->Mat[v1][v2];
	// 1
	if(w==0)
	{
		g->E[e_index].endV1 = NULL;
		g->E[e_index].endV2 = NULL;
		g->E[e_index].w = 0;

		g->Mat[v1][v2] = -1;
		g->Mat[v2][v1] = -1;
	}
	// 2
	else g->E[e_index].w = w;

}