Native/C

링크드 리스트 (Linked list)

aucd29 2013. 10. 2. 18:51
/***************************************************************************
*
*        Date        : 2005-04-27
*        Copyright    : aucd29
*        E-mail        : aucd29@daum.net
*
*        1. 주어진 연결 리스트를 역순화 시키는 함수 invert를 만들어라
*
***************************************************************************/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define YES 1
#define NO 0
#define LIST struct list

#define _ERR_MEMORY "메모리 생성 불가능"

LIST {
    char *name;
    char sex;
    int age;
    LIST *nextp;
};

int inp(char *, char *, int *);
LIST *node(LIST *, char *, char, int);
void prn(LIST *);

//
// 추가 과제물
//
LIST *invert(LIST *);

int main(int argc, char *argv[])
{
    LIST *root;
    char in[20], sx;
    int ag;

    root = NULL;

    while(inp(in, &sx, &ag) == NO)
        root = node(root, in, sx, ag);

    puts("Name        Sex        Age\n");
    puts("--------------------------\n");
    prn(root);

    root = invert(root);
    puts("------------- invert ----------");
    prn(root);

    return 0;
}

//
// Type        : Recursive
// Return    : struct type
// 입력받은 이름,성별, 나이를 링크드 리스트 형식에 넣는다.
//
LIST *node(LIST *rp, char *nin, char nsx, int nag)
{
    if(rp == NULL)
    {
        char *temp = NULL;
        if(!(rp = (LIST *)malloc(sizeof(LIST))))
            puts(_ERR_MEMORY);
        if(!(temp = (char *)malloc(strlen(nin)+1)))
            puts(_ERR_MEMORY);

        strcpy(temp,nin);
        rp->name = temp;
        rp->sex = nsx;
        rp->age = nag;
        rp->nextp = NULL;
    }
    else rp->nextp = node(rp->nextp, nin, nsx, nag);

    return rp;
}

//
// x x x 입력받은 내용을 변수에 저장한다.
//
int inp(char *iin, char *isx, int *iag)
{
    printf("Name        Sex        Age -----> ");
    scanf("%s %c %d",iin, isx, iag);
    if(*iin == 'x')
        return (YES);
    return (NO);
}

//
// 링크드 리스트를 출력한다.
//
void prn(LIST *ps)
{
    for(; ps; ps = ps->nextp)
        printf("%-8s%-4c%d\n",ps->name, ps->sex, ps->age);
}

//
// 과제
// 해당 링크드 리스트를 역순화 시킨다.
//
LIST* invert(LIST *root)
{
    LIST *trail, *middle, *lead = root->nextp;
    
    //
    // 초기화 작업으로 lead에 root->nextp 즉 두번째 위치(root->nextp)를 가르키고
    // 그 다음 middle에 첫번째(root)를 가르키게 한다음 trail은 null 값을 주고
    // root->nextp 는 \0 로 바꾼다.
    //
    middle = root;
    trail = NULL;
    root->nextp = '\0';

    while(lead!='\0')
    {
        trail = middle;
        middle = lead;
        if(lead->nextp == '\0')
        {
            root = lead;
            lead = '\0';
        }
        else
            lead = lead->nextp;
        middle->nextp = trail;
    }

    return root;
}