[C언어 소스] 단일(단순) 연결리스트, 역순 보관

안녕하세요. 언제나 휴일이예요.

이번에는 단일 연결리스트(단순 연결리스트라고도 부릅니다.) 소스 코드입니다. 여기에서는 자료를 추가하는 역순으로 보관합니다.

단순 연결리스트
단순 연결리스트

단일 연결리스트의 노드를 정의하고 연결리스트 초기화, 자료 추가, 자료 삭제, 자료 검색, 전체 자료 출력, 연결리스트의 모든 노드 해제화 기능을 제공합니다.

단일 연결리스트 역순 보관 실행 화면
단일 연결리스트 – 역순 보관(가장 최근에 보관한 데이터가 맨 앞)

소스 코드

//단일 연결리스트 - 역순 보관(가장 최근에 보관한 데이터가 맨 앞)
//노드 정의, 초기화, 추가, 삭제, 검색, 전체 출력, 해제
#include <stdio.h>
#include <stdlib.h>

typedef struct Node//노드 정의
{
    int data;//데이터
    struct Node *next;//링크(다음 노드의 위치 정보)
}Node;

void InitList(Node **phead);//초기화
void AddData(Node **phead, int data);//데이터 추가
void Remove(Node **phead, Node *now);//노드 삭제
Node *Find(Node *seek, int data);//노드 검색
void ViewAll(Node *head);//전체 출력
void Clear(Node **head);//해제

int main(void)
{
    Node *head;
    {//초기화 및 추가 테스트를 위한 블록
        InitList(&head);
        AddData(&head, 3); //3
        AddData(&head, 4); //4 3
        AddData(&head, 6); //6 4 3
        AddData(&head, 9); //9 6 4 3
        ViewAll(head);// 9 6 4 3 출력
    }

    {//검색과 삭제 테스트를 위한 블록
        Node *seek = Find(head, 4);
        if (seek)
        {
            printf("4를 보관한 노드를 찾았음\n");
            Remove(&head, seek); //9 6 3
            printf("4를 보관한 노드 제거 후\n");
            ViewAll(head);// 9 6 3 출력
        }
    }
    Clear(&head);//전체 해제
    printf("전체 해제 후\n");
    ViewAll(head);// 아무것도 출력하지 않음

    return 0;
}

void InitList(Node **phead)
{
    *phead = NULL;
}
void AddData(Node **phead, int data)
{
    Node *now = (Node *)malloc(sizeof(Node));//새로운 노드 생성
    now->data = data; //생성한 노드에 data 설정

                      //*phead는 리스트의 맨 앞에 노드의 위치 정보입니다.
    now->next = (*phead);//새로 생성한 노드의 next를 (*phead)로 설정
    *phead = now;//(*phead)를 now로 설정
}

void Remove(Node **phead, Node *now)
{
    Node *prev = NULL;
    Node *seek = *phead;

    if (*phead == now)//삭제할 노드가 맨 앞 노드와 같다면
    {
        (*phead) = now->next;//맨 앞 노드는 now의 next로 설정
        free(*phead);//맨 앞 노드 메모리 해제        
        return;//함수 종료
    }

    while (seek) //seek가 참이면(NULL 이 아니면)
    {
        if (seek == now)//seek가 now와 같을 때
        {
            prev->next = seek->next;//이전 노드의 next를 seek의 next로 설정
            free(seek);
            return;//함수 종료
        }
        prev = seek;//seek를 변경하기 전에 prev에 기억
        seek = seek->next;//seek를 다음으로 이동
    }
}

Node *Find(Node *seek, int data)
{
    while (seek) //seek가 참이면(NULL 이 아니면)
    {
        if (seek->data == data)//찾았을 때
        {
            return seek;
        }
        seek = seek->next;//seek를 다음으로 이동
    }
    return NULL;//못 찾았을 때
}
void ViewAll(Node *head)
{
    Node *seek = head;
    int i = 0;
    while (seek) //seek가 참이면(NULL 이 아니면)
    {
        i++;
        printf("[%2d]:%-05d ", i, seek->data);

        if (i % 5 == 0)//5의 배수일 때
        {
            printf("\n");//개행
        }
        seek = seek->next;//seek를 다음으로 이동
    }
    printf("\n");
}

void Clear(Node **head)
{
    Node *prev = NULL;
    Node *seek = *head;
    while (seek) //seek가 참이면(NULL 이 아니면)
    {
        prev = seek;//seek를 변경하기 전에 prev에 기억
        seek = seek->next;//seek를 다음으로 이동
        free(prev);//이전 노드 메모리 해제
    }
    *head = NULL;//이제 맨 앞 노드가 없음
}