☑️ 연결리스트 개념
- 정의
- 하나의 링크 필드를 가진 노드들이, 모두 자기 후속 노드와 연결되어 있는 리스트
- 마지막 노드는 리스트 끝을 표시하는
null
값을 가짐
- 같은 용어
- 선형 연결 리스트 (linear linked list)
- 단순 연결 선형 리스트 (singly linked linear list)
- 연결 리스트 (linked list)
☑️ 구조체 및 메서드 선언
#define IS_FULL(ptr) (!(ptr))
#define IS_EMPTY(ptr) (!(ptr))
typedef struct listNode {
int data;
struct listNode* link;
}list_node;
typedef struct{
listNode* head;
}linkedList_h;
☑️ 생성 알고리즘
linkedList_h* createLinkedList_h (void) {
linkedList_h* L;
L = (linkedList_h*)malloc(sizeof(linkedList_h));
L->head = NULL;
return L;
}
☑️ 해제 알고리즘
void freeLinkedList_h(linkedList_h* L) {
listNode* p;
while(L->head != NULL){
p = L->head;
L->head = L->head->link;
free(p);
p = NULL;
}
}
☑️ 삽입 알고리즘
void insert (listNode* ptr, listNode* node, int x){
listNode* newNode;
newNode = (listNode*r) malloc (sizeof(listNode));
newNode.data = x;
if (IS_FULL(newNode)){
fprintf(stderr, "The memory is full\n");
exit(1);
}
if (node == NULL) {
L = newNode;
newNode->link = NULL;
}
else if (ptr == NULL){
newNode->link = node;
node = newNode;
}
else {
newNode->link = ptr->link;
ptr->link = newNode;
}
}
- 포인터 변수 ptr이 가리키는 list에서 또 다른 포인터 변수 node가 가리키는 node(값이 x인) 다음에 새로운 node 삽입
- (1)node가 null인 경우, (2)ptr이 null인 경우, (3)node와 ptr이 null이 아닌경우로 나누어 구현
☑️ 마지막 노드 삽입 알고리즘
void addLastNode(linkedList_h* L, int x){
listNode* newNode = (listNode*) malloc (sizeof(listNode));
newNode->data = x;
newNode->link = NULL;
if (node==NULL) {
L->head = newNode;
return;
}
listNode* p = L->head;
while (p->link != NULL){
p = p->link;
}
p->link = newNode;
}
☑️ 삭제 알고리즘

void delete(list_pointer *ptr, list_pointer trail, list_pointer node){
if (node==NULL) {
exit(1);
}
if (trail){
trail->link = node->link;
} else {
ptr = node->link;
}
free(node);
}
- 변수 ptr이 가리키는 list 내에, 포인터 변수 node가 가리키는 node 삭제
- trail은 변수 node가 가리키는 node의 바로 앞 node를 가리킴 (trail.link == node)
- 맨 앞 node를 삭제할 경우, node=ptr, trail=NULL
☑️ 마지막 노드 삭제 알고리즘
void deleteLastNode(linkedList_h* L){
listNode* previous;
listNode* current;
if(L == NULL) return;
if(L->link == NULL) {
free(L);
L = NULL;
}
else {
previous = L;
current = L->link;
while(current->link != NULL){
previous = current;
current = current.link;
}
free(current);
previous.link = NULL;
}
}
☑️ 역순변환 알고리즘

void reverse(linkedList_h* L){
listNode* lead <- L
listNode* middle = NULL;
listNode* trail = NULL;
while(**lead != null**) {
trail = middle;
middle = lead;
lead = lead.link;
**middle.link = trail**;
}
L->head = middle;
}
- lead(가장 앞), middle(중간), trail(가장 뒤) 3개의 포인터를 이용하여 처리
- middle이 현재 lead 위치를 지킴 > lead는 앞으로 전진 > middle의 링크 방향을 역으로 바꿈
☑️ 연결리스트 출력 알고리즘
void printList(linkedList_h* L){
listNode* p;
p = L.head;
printf("(");
while(p != NULL) {
printf("%d", p.data);
p=p.link;
if(p!=NULL) printf(", ");
}
printf(")\n");
}
☑️ main 함수
int main(){
linkedList_h* L;
L = createLinkedList_h();
addLastNode(L, 1);
addLastNode(L, 2);
addLastNode(L, 3);
deleteLastNode(L);
reverse(L);
printList(L);
}