Linked List
LG-T 프로젝트시 Script compiler를 만들면서 단순하지만 유용하게 잘 사용했던 link list 2종-세트 대방출~
1. 단방향 Linked List
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
/* ------- Linked List의 데이터 타입 ------- */
typedef struct{
/* ---- 다음 Node 를 가리킬 포인터 ---- */
/* ---- 단방양이므로 한쪽 포인터만 있으면 된다. -- */
void *next;
/* ---- 이하는 데이터 필드 ----- */
char MenuType;
char menuId[12];
char name[128];
}ITEM;
/* ------- Linked List 의 첫번째 헤더
---------- 단방향이므로 하나만 있으면 된다. ---- */
ITEM *f_node;
int insertNode(ITEM *tmp)
{
ITEM *cc;
/* -- cc 라는 이름으로 ITEM 타입의 메모리를 할당한다. -- */
cc = (ITEM *)malloc(sizeof(ITEM));
/* -- 입력데이터를 방금 만든 메모리로 copy 한다. -- */
memcpy(cc, tmp, sizeof(ITEM));
/* -- 입력된 데이터가 하나도 없다면.. -- */
if(!f_node->next)
{
/* -- 첫번째 노드뒤에 연결 시킨다 -- */
f_node->next = (void *)cc;
} else {
/* -- 첫번째 노드의 다음 링크를
추가될 노드의 다음 링크로 설정한다. -- */
cc->next = f_node->next;
/* -- 첫번째 노드의 다음 링크를
추가된 노드로 설정한다. -- */
f_node->next = cc;
}
return 1;
}
void listView()
{
ITEM *cc;
/* ---- 첫 헤더의 다음 링크의 주소를 cc 로 설정한다. -- */
cc = (ITEM *)f_node->next;
while(cc)
{
/* --- 노드의 데이터를 출력한다 ---- */
printf("--------------\n");
printf("type:[%c]\n", cc->MenuType);
printf("menu:[%s]\n", cc->menuId);
printf("name:[%s]\n", cc->name);
/* --- 다음 노드로 이동한다. --- */
cc = (ITEM *)cc->next;
}
}
int main(int argc ,char **argv)
{
ITEM asd;
/* ----- 첫번째 노드의 메모리를 설정한다 ------- */
f_node = (ITEM *)malloc(sizeof(ITEM));
/* ----- 첫번째 노드의 다음 링크를 NULL로 설정한다. --- */
f_node->next = NULL;
memset(&asd, 0x00, sizeof(asd));
/* ---- 노드에 데이터를 입력하고 노드를 추가한다. ------ */
asd.MenuType = 'I';
sprintf(asd.menuId,">진익섭 1");
sprintf(asd.name, "즐겨찾기");
insertNode(&asd);
asd.MenuType = 'A';
sprintf(asd.menuId,">진익섭 2");
sprintf(asd.name, "관광명소");
insertNode(&asd);
asd.MenuType = 'B';
sprintf(asd.menuId,">진익섭 3");
sprintf(asd.name, "주요은행");
insertNode(&asd);
asd.MenuType = 'C';
sprintf(asd.menuId,">진익섭 3");
sprintf(asd.name, "관공서");
insertNode(&asd);
/* ----- Linked List 를 확인한다. ------ */
listView();
return 1;
}
2. 양방향 Linked List
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
/* 앞의 Node 를 가리키는 포인트 주소 */
void *prev;
/* 뒤의 Node 를 가리키는 포인트 주소 */
void *next;
char MenuType;
char menuId[12];
char name[128];
}ITEM;
/* 시작 Node */
ITEM *f_node;
/* 마지막 꼬리 Node */
ITEM *l_node;
/* 맨 마지막에 데이터를 집어 넣는 함수(즉 꼬리 Node 바로 앞에 넣는다) */
int push_back(ITEM *tmp)
{
ITEM *cc;
cc = (ITEM *)malloc(sizeof(ITEM));
memcpy(cc, tmp, sizeof(ITEM));
/* -- 추가할 Node의 다음 Node를 꼬리 Node로 한다. -- */
cc->next = l_node;
/* -- 추가할 Node의 바로 앞 Node를 꼬리 노드의 앞 Node로 한다. -- */
cc->prev = l_node->prev;
/* -- 바로 앞 Node의 다음 노드로 자신으로 설정한다. -- */
/* -- prev는 ITEM형 포인트로 설정해 주어야 한다.(중요) --*/
((ITEM *)l_node->prev)->next = cc;
/* -- 꼬리 Node의 바로 앞 Node를 자신으로 설정한다. -- */
l_node->prev = cc;
return 1;
}
int push_front(ITEM *tmp)
{
ITEM *cc;
cc = (ITEM *)malloc(sizeof(ITEM));
memcpy(cc, tmp, sizeof(ITEM));
/* -- 추가할 Node의 다음 Node를 헤더 Node의 다음 Node로 설정한다. -- */
cc->next = f_node->next;
/* -- 자신의 앞 Node를 헤더로 설정한다. -- */
cc->prev = f_node;
/* -- 자신의 앞 Node의 다음 Node를 가리키는 포인터가 자신을 가리키도록 한다.(next는 ITEM형 포인터로 캐스팅 해 주어야 한다) -- */
((ITEM *)f_node->next)->prev = cc;
/* -- 헤더 Node를 자신으로 설정한다. -- */
f_node->next = cc;
return 1;
}
void listView()
{
ITEM *cc;
cc = (ITEM *)f_node->next;
while(cc != l_node)
{
printf("--------------\n");
printf("type:[%c]\n", cc->MenuType);
printf("menu:[%s]\n", cc->menuId);
printf("name:[%s]\n", cc->name);
cc = (ITEM *)cc->next;
}
free(cc);
}
int main(int argc ,char **argv)
{
ITEM asd;
/* -- Header, Tail Node 초기화 -- */
f_node = (ITEM *)malloc(sizeof(ITEM));
l_node = (ITEM *)malloc(sizeof(ITEM));
/* -- 헤더 Node의 앞은 NULL, 뒤는 꼬리 Node로 초기화 -- */
f_node->prev = NULL;
f_node->next = l_node;
/* -- 꼬리 Node의 앞은 헤더 Node로 뒤는 Null로 초기화 -- */
l_node->prev = f_node;
l_node->next = NULL;
memset(&asd, 0x00, sizeof(asd));
asd.MenuType = 'A';
sprintf(asd.menuId,">진익섭 1");
sprintf(asd.name, "즐겨찾기");
/* -- 링크의 맨뒤에 넣는다 -- */
push_back(&asd);
asd.MenuType = 'B';
sprintf(asd.menuId,">진익섭 2");
sprintf(asd.name, "관광명소");
/* -- 링크의 맨뒤에 넣는다 -- */
push_back(&asd);
asd.MenuType = 'C';
sprintf(asd.menuId,">진익섭 3");
sprintf(asd.name, "주요은행");
/* -- 링크의 맨앞에 넣는다 -- */
push_front(&asd);
asd.MenuType = 'D';
sprintf(asd.menuId,">진익섭 3");
sprintf(asd.name, "관공서");
/* -- 링크의 맨앞에 넣는다 -- */
push_front(&asd);
listView();
return 1;
}