■Double Linked List■
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #ifndef DLIST_H #define DLIST_H #include <stdlib.h> typedef struct DListElmt_ { void *data; struct DListElmt_ *prev; struct DListElmt_ *next; } DListElmt; typedef struct DList_ { int size; int (*match)(const void *key1, const void *key2); void (*destroy)(void *data); DListElmt *head; DListElmt *tail; } DList; | cs |
대표적으로 insert를 구현하면서 이해를 해보면 delete,find등 다른 구현은 쉽게할 수있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | void dlist_init(DList *list, void (*destroy)(void *data)) { /***************************************************************************** * * * Initialize the list. * * * *****************************************************************************/ list->size = 0; list->destroy = destroy; list->head = NULL; list->tail = NULL; return; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | int dlist_ins_next(DList *list, DListElmt *element, const void *data) { { DListElmt *new_element; if ((new_element = (DListElmt *)malloc(sizeof(DListElmt))) == NULL) return -1; new_element->data = (void *)data; if (element == NULL) { if (dlist_size(list) == 0) { list->head = new_element; list->head->prev = NULL; list->head->next = NULL; list->tail = new_element; } else { new_element->next=list->tail->next; list->tail->next=new_element; list->tail = new_element; list->tail->prev=list->head; } } else { if (dlist_size(list) == 0) { list->head = new_element; list->head->prev = NULL; list->head->next = NULL; list->tail = new_element; } else { new_element->next=element->next; element->next=new_element; element = new_element; new_element->prev=element; } } list->size++; return 0; } } | cs |
1. 전달된 노드의 값이 NULL인지 존재하는지를 구분한다. (노드가 존재하면 그 노드를 기준으로 insert 한다.)
2. size가 0인지를 즉, List안에 처음으로 들어갈 노드인지 아닌지를 체크한다.
3.
if (dlist_size(list) == 0)
{
list->head = new_element;
list->head->prev = NULL;
list->head->next = NULL;
list->tail = new_element;
}
size가 0, List안에 처음으로 들어갈 때의 노드를 A라고 하자, 하나 밖에 없으므로 head와 tail은 A_node를 가리키고,
A_node의 앞,뒤에는 아무것도 없으므로 NULL값을 넣어준다.
list->head(list의 head=new_element head가 new_element를 가리킨다.)
list->head->prev = NULL(head가 가리키는 노드의 prev에 NULL을 넣는다.)
4.
else
{
new_element->next=list->tail->next;
list->tail->next=new_element;
list->tail = new_element;
list->tail->prev=list->head;
}
기존에 A_node가 있을 때 B_node가 들어간다고 가정한다면
먼저 B_node의 next에 list->tail->next(즉, A_node의 next값을 넣어준다(현재 A_node의 next값은 NULL이다)
list->tail->next(A_node의 next)는 B_node를 가리킨다.
list->tail(List의 끝은)B_node를 가리키고
list->tail->prev(B_node의 prev)는 list->head(A_node)를 가리킨다.
*전달된 노드가 있을 시 list->tail를 element로 바꿔주면 되고 현재는 insert_next로 구현하였고 insert_prev로 구현할 수도 있다.
예) insert_next : insert- 1 2 3 4 insert된 node -4 3 2 1
'자료구조' 카테고리의 다른 글
[자료구조_Day5]biTree,bsTree (0) | 2018.11.06 |
---|---|
[자료구조_Day4]Chained Hash Tables (0) | 2018.11.06 |
[자료구조_Day3]Stack (0) | 2018.11.06 |
[자료구조_Day3]Set (0) | 2018.11.06 |
[자료구조_Day2]Double Circular Linked List (0) | 2018.10.28 |