어제 이어서…

오류를 해결했다.

우선 어제 고민했던 함수 포인터는, 그냥 함수포인터변수 하나 새로 만들어서 인자로 전달하는 방식으로 해결했다. 배열처럼 함수이름도 identifier니까, 포인터 파라미터 자리에 함수 이름쓰면 되지 않을까? 했었는데… 배열과 함수는 차이도 많고, 그리고 애초에 파라미터 자료형이 함수포인터니까 맘 편하게 함수포인터를 주는 것으로 스스로 합의봤다.

//정렬 기준 할당
	int (*pf)(LData*, LData*) = Ascending;
	SetSortRule(&list, *pf);

그리고 실행하니까 실행은 되는데, 출력이 안되는 오류 발생… 무엇이 문제일까 한줄씩 디버그 하다가, 문제를 찾았다.

void SInsert(List * plist, LData data)
{
	Node * newNode = (Node*)malloc(sizeof(Node));
	Node * pred = plist->head;
	newNode->data = data;

	while(pred->next != NULL &&
		plist->comp(data, pred->next->data) != 0)
	{
		pred = pred->next;
	}

	newNode->next = pred->next;
	pred->next = newNode;

	(plist->numOfData)++;
}

보니까 numOfData는 수가 증가하는데, 탐색 과정에서 하나도 탐색이 안되고 있었음. 노드가 끊긴게 아닐까 싶어서… SInsert함수를 찾아봤다. 아니나 다를까,

	newNode->next = pred->next;
	**pred->next = newNode->next;**

여기가 이렇게 되어있었다.

최초 시행때를 그려보자. newNode→next는 NULL이다. 여기에 pred→next할당하는 거 까진 좋다. 그게 NULL이어도…

문제는 pred→nextnewNode→next를 할당하게 되어있어서, head바로 다음부터 NULL로 노드가 끊겨버린 것이고, 이게 모든 시행에 적용되었던 것이다. 그래서 실행은 되는데, head다음 노드 주소를 몰라서 탐색이 안되었던 것이었음..

약간 어려운 문제는…

void SInsert(List * plist, LData data)
{
	Node * newNode = (Node*)malloc(sizeof(Node));
	Node * pred = plist->head;
	newNode->data = data;

	while(pred->next != NULL &&
		**plist->comp(data, pred->next->data) != 0)**
	{
		pred = pred->next;
	}

	newNode->next = pred->next;
	pred->next = newNode;

	(plist->numOfData)++;
}

조건이 &&로 연결되어있어서, 단순히 Descending()에서 분기 조건문을

int Descending(LData* newdata, LData* curdata) //내림차순 정렬
{
	if (newdata **<=** curdata)
		return FALSE; //0
	else
		return TRUE; //1		
}

로바꾼다고 바로 Ascending이 되지 않는다는 것이다.. 비트연산을 생각하고 적절하게 조건을 바꾸어줘야 한다. 안그럼 SInsert()내의 while이 폭주해서.. 오버플로우가 일어난다.

연결리스트의 정렬 삽입의 구현(2)

윤성우의 열혈 자료구조 04-3 ②