카테고리 없음
[C/정렬] 양방향(이중) 연결리스트(Double Linked List)
미친토끼
2021. 2. 28. 09:17
//doubleLinkedList.c
// 참고 유튜브 영상: "Gunny's Algorithm Together"의 "더블 링크드 리스트 다함께 C언어로 코딩 해봐요 - by Gunny (Korean Ver.)"
#include <stdio.h>
#include <stdlib.h>
typedef struct _Node{
int data;
struct _Node *next;
struct _Node *prev;
} Node;
// 노드 만들기, 값은 초기화
Node *createNode(int data) {
Node *newNode = (Node *) malloc(sizeof(Node));
newNode->data = data;
newNode->prev = NULL;
newNode->next = NULL;
return newNode;
}
//노드의 메모리를 해제함.
void deleteNode(Node *node) {
free(node);
}
//head부터 시작해서 index번째의 Node의 주소를 반환함
Node *getNodeAt(Node *head, int index) {
Node *curr = head;
int count = 0;
while(curr != NULL) {
if(count == index) {
return curr;
}
count++;
curr = curr->next;
}
return NULL;
}
//Node의 갯수를 알려주는 함수.
int countNode(Node *head) {
Node *curr = head;
int count = 0;
while (curr != NULL) {
count++;
curr = curr->next;
}
return count;
}
void appendNode(Node **head, Node *newNode) {
// 노드가 하나도 없는 경우
if (*head == NULL) {
*head = newNode;
} else {
Node *curr = *head;
while(curr->next != NULL) {
curr = curr->next;
}
//curr 이 마지막 노드임, 그 뒤에 노드를 추가
curr->next = newNode;
newNode->prev = curr;
//newNode->next = NULL;
}
}
void insertAfter(Node *curr, Node *newNode) {
//createNode 함수로 만든 노드를 curr 뒤에 끼워넣음.
//curr 이 head일 경우
if (curr->prev == NULL && curr->next == NULL) {
curr->next = newNode;
newNode->prev = curr;
} else if (curr->next == NULL) { //tail 일 경우
curr->next = newNode;
newNode->prev = curr;
} else { //body 일 경우, 사이에 끼워넣는다.
newNode->next = curr->next;
newNode->prev = curr;
curr->next->prev = newNode;
curr->next = newNode;
}
}
void removeNode(Node **head, Node* remove) {
//헤드를 제거하라고 한다면
if (*head == remove) {
*head = remove->next;
}
remove->next->prev = NULL;
// remove 할 것 뒤에 노드가 있을 때...
if (remove->next != NULL) {
remove->next->prev = remove->prev;
}
//remove 앞에 노드가 있을 때...
if (remove->prev != NULL) {
remove->prev->next = remove->next;
}
deleteNode(remove);
}
void printNode(Node *head, int count) {
Node *curr = head;
for (int i = 0; curr != NULL && i < count; i++) { // 0 < 5
curr = getNodeAt(head, i);
printf("list[%d] = %d\n", i, curr->data);
}
}
int main () {
int i = 0;
int count = 0;
// 트리의 첫번째 노드를 가리키는 포인터 변수. head는 변경될 수 있으므로 그 head를 가리킨다.
// head와 동일한 메모리 값이지만 함수 내에서 list 메모리값을 바꾸어 head 위치를 변경하기도 한다.
Node *list = NULL;
//임시 노드
Node *newNode = NULL;
// 현재 노드
Node *curr = NULL;
//i를 데이터값으로, 양방향 주소를 NULL로 하는 Node 형 포인터 5개 만들어 list 주소에 하나씩 추가한다.
for(i=1; i<6; i++) {
newNode = createNode(i);
printf("%d번째 노드:0x%x, data:%d, prev:0x%x, next:0x%x\n", \
i-1, newNode, newNode->data, newNode->prev, newNode->next);
printf("list:0x%x\n", list);
appendNode(&list, newNode);
printf("newNode->prev:0x%x\n", newNode->prev);
printf("newNode->next:0x%x\n", newNode->next);
}
count = countNode(list); // 노드의 전체 갯수 구하기 = 5
printf("node의 개수: %d\n", count);
for (i = 0; i<count; i++) { //5회 반복
curr = getNodeAt(list, i); // 0, 1, 2, 3, 4번째 있는 노드 주소를 얻기
printf("list[%d] = %d\n", i, curr->data); // 그 노드의 데이터 출력
}
printf("--------------5 Nodes Created------------\n");
newNode = createNode(99);
curr = getNodeAt(list, 0); // 첫번째 노드의 포인터
insertAfter(curr, newNode); // 그 노드 뒤에 새 노드를 삽입하기
newNode = createNode(1033);
curr = getNodeAt(list, 4);
insertAfter(curr, newNode);
count = countNode(list);
printNode(list, count);
// for (i = 0; i< count; i++) {
// curr = getNodeAt(list, i);
// printf("list[%d] = %d\n", i, curr->data);
// }
printf("----------- After 2 nodes inserted-----------\n");
newNode = getNodeAt(list, 1);
removeNode(&list, newNode);
count = countNode(list);
printNode(list, count);
printf("---After Nodes with index 1 removed-----\n");
newNode = getNodeAt(list, 0);
removeNode(&list, newNode);
count = countNode(list);
printNode(list, count);
printf("---After Nodes with index 0 removed-----\n");
return 0;
}
------------실행 결과-----------
0번째 노드:0x4052a0, data:1, prev:0x0, next:0x0
list:0x0
newNode->prev:0x0
newNode->next:0x0
1번째 노드:0x4056d0, data:2, prev:0x0, next:0x0
list:0x4052a0
newNode->prev:0x4052a0
newNode->next:0x0
2번째 노드:0x4056f0, data:3, prev:0x0, next:0x0
list:0x4052a0
newNode->prev:0x4056d0
newNode->next:0x0
3번째 노드:0x405710, data:4, prev:0x0, next:0x0
list:0x4052a0
newNode->prev:0x4056f0
newNode->next:0x0
4번째 노드:0x405730, data:5, prev:0x0, next:0x0
list:0x4052a0
newNode->prev:0x405710
newNode->next:0x0
node의 개수: 5
list[0] = 1
list[1] = 2
list[2] = 3
list[3] = 4
list[4] = 5
--------------5 Nodes Created------------
list[0] = 1
list[1] = 99
list[2] = 2
list[3] = 3
list[4] = 4
list[5] = 1033
list[6] = 5
----------- After 2 nodes inserted-----------
list[0] = 1
list[1] = 2
list[2] = 3
list[3] = 4
list[4] = 1033
list[5] = 5
---After Nodes with index 1 removed-----
list[0] = 2
list[1] = 3
list[2] = 4
list[3] = 1033
list[4] = 5
---After Nodes with index 0 removed-----