연결 리스트 연습 문서의 문제 1 풀이 코드다.
/* 연결 리스트 연습 문제 1: 체인 따라가기.
*
* 문서: 1-2학기/자료구조/4.연습문제/19.연결 리스트 연습.md
* printList, length, indexOf는 "링크를 따라간다"를 반복문으로 묶은 것이다.
* 실행: cc -std=c11 -Wall -Wextra 19_linked-list-practice_p1.c -o p1 && ./p1
* 번호: 노드 번호는 0부터 센다.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int failures = 0;
static void check(int ok, const char *what)
{
if (!ok) { printf("FAIL: %s\n", what); failures++; }
}
typedef struct listNode *listPointer;
typedef struct listNode {
char data;
listPointer link;
} listNode;
static long liveNodes = 0;
/* ---------- 문서에 실은 코드 ---------- */
/* 원소를 맨 앞부터 차례로 out에 적는다 */
void printList(listPointer first, char *out)
{
int n = 0;
for (listPointer p = first; p != NULL; p = p->link) /* NULL에 닿을 때까지 링크를 따라간다 */
out[n++] = p->data;
out[n] = '\0';
}
/* 노드 수 */
int length(listPointer first)
{
int n = 0;
for (listPointer p = first; p != NULL; p = p->link) n++;
return n;
}
/* x가 든 첫 노드의 번호. 없으면 -1 */
int indexOf(listPointer first, char x)
{
int k = 0;
for (listPointer p = first; p != NULL; p = p->link, k++)
if (p->data == x) return k;
return -1;
}
/* ---------- 여기부터 테스트 ---------- */
static listPointer build(const char *s)
{
listPointer first = NULL;
for (int i = (int)strlen(s) - 1; i >= 0; i--) {
listPointer node = malloc(sizeof(*node));
if (node == NULL) { fprintf(stderr, "Insufficient memory\n"); exit(EXIT_FAILURE); }
liveNodes++;
node->data = s[i];
node->link = first;
first = node;
}
return first;
}
static void freeList(listPointer first)
{
while (first != NULL) { listPointer d = first; first = first->link; free(d); liveNodes--; }
}
int main(void)
{
char out[64];
listPointer first = build("abcde");
/* (가) ~ (다) */
check(first->link->link->data == 'c', "(가) first->link->link->data는 c");
check(first->link->link->link->link->data == 'e', "(나) 링크 네 번이면 e");
check(first->link->link->link->link->link == NULL, "(다) 링크 다섯 번이면 NULL");
/* (라) */
printList(first, out);
check(strcmp(out, "abcde") == 0 && length(first) == 5, "(라) printList는 abcde, length는 5");
check(indexOf(first, 'a') == 0 && indexOf(first, 'd') == 3 && indexOf(first, 'z') == -1, "변형: indexOf");
/* 빈 목록과 노드 하나 */
printList(NULL, out);
check(strcmp(out, "") == 0 && length(NULL) == 0 && indexOf(NULL, 'a') == -1, "빈 목록");
listPointer one = build("q");
printList(one, out);
check(strcmp(out, "q") == 0 && length(one) == 1 && one->link == NULL, "노드 하나");
freeList(one);
freeList(first);
check(liveNodes == 0, "malloc 횟수 = free 횟수");
if (failures) { printf("%d개 실패\n", failures); return 1; }
printf("ALL CHECKS PASSED\n");
return 0;
}