728x90
728x90
이중 연결 리스트(Doubly Linked List)
- 응용 프로그램에서의 특정 노드에서 양방향으로 자유롭게 움직일 수 있는 리스트 구조
- 하나의 노드가 선행 노드와 후속 노드에 대한 두 개의 링크를 가지는 리스트
- 링크가 양방향이므로 양방향으로 검색이 가능해진다.
- 공간을 많이 차지하고 코드가 복잡해진다는 단점이 있다.
- 실제 응용에서는 이중 연결 리스트와 원형 연결 리스트를 혼합한 형태가 많이 사용된다.
- 헤드 노드(Head Node)라는 특별한 노드를 추가하는 경우가 많다.
- 헤드 노드는 데이터를 가지고 있지 않은 특별한 노드를 의미한다.
- 헤드 포인터 : 리스트의 첫 번째 노드를 가리키는 포인터
- 헤드 노드가 존재하면 삽입, 삭제 알고리즘이 간편해진다.
- 이중 연결 리스트에서의 노드는 3개의 필드(왼쪽 링크 필드, 데이터 필드, 오른쪽 링크 필드)로 이루어져 있다.
- 링크 필드에는 포인터가 저장된다.
코드
#include <stdio.h> #include <stdlib.h> #include <memory.h> #include <string.h> typedef int element; typedef struct DlistNode { element data; struct DlistNode *llink; struct DlistNode *rlink; } DlistNode; // 이중 연결 리스트를 초기화 void init(DlistNode *phead) { phead->llink = phead; phead->rlink = phead; } // 이중 연결 리스트의 노드를 출력 void display(DlistNode *phead) { DlistNode *p; for (p = phead->rlink; p != phead; p = p->rlink) { printf("<--- | %x | %d | %x | ---->\n", p->llink, p->data, p->rlink); } printf("\n"); } // 노드 new_node를 노드 before의 오른쪽에 삽입 void dinsert_node(DlistNode *before, DlistNode *new_node) { new_node->llink = before; new_node->rlink = before->rlink; before->rlink->llink = new_node; before->rlink = new_node; } // 노드 removed를 삭제 void dremove_node(DlistNode *phead_node, DlistNode *removed) { if (removed == phead_node) return; removed->llink->rlink = removed->rlink; removed->rlink->llink = removed->llink; free(removed); } // 원하는 원소를 탐색 DlistNode *dsearch(DlistNode *head_node, element x) { DlistNode *p; p = head_node; do { if (p->data == x) return p; // 탐색 성공 p = p->rlink; // 오른쪽 링크따라 이동 } while (p != head_node); return NULL; // 탐색 실패 } // 두 리스트를 연결 DlistNode *dconcat(DlistNode *head1, DlistNode *head2) { if (head1 == head1->rlink) return head2; // head1이 공백인 경우 else if (head2 == head2->rlink) return head1; // head2가 공백인 경우 else { // 둘 다 공백이 아닌 경우 head2->rlink->llink = head1->llink; head1->llink->rlink = head2->rlink; head2->llink->rlink = head1; head1->llink = head2->llink; head2->rlink = head2; head2->llink = head2; return head1; } } // 모든 노드를 삭제 DlistNode dremove_all(DlistNode *head_node) { DlistNode *removed = head_node->rlink; // head노드의 오른쪽 노드 삭제 if (head_node == head_node->rlink) return; // 공백이면 종료 while (removed != head_node) { // 삭제할 노드가 head가 아닌 동안 반복 removed->llink->rlink = removed->rlink; removed->rlink->llink = removed->llink; free(removed); removed = head_node->rlink; } } // 교재 main 함수 수정 void main() { DlistNode head_node, head_node2; DlistNode *phead_node = &head_node; DlistNode *p[10], *p2[10]; int i; init(&head_node); init(&head_node2); for (i = 0; i < 5; i++) { p[i] = (DlistNode *)malloc(sizeof(DlistNode)); p[i]->data = i; // 헤드 노드의 오른쪽에 삽입 dinsert_node(&head_node, p[i]); } display(&head_node); getchar(); if (dsearch(&head_node, 3)) printf("찾음\n"); else printf("없음\n"); if (dsearch(&head_node, 10)) printf("찾음\n"); else printf("없음\n"); dremove_node(&head_node, p[4]); display(&head_node); getchar(); for (i = 0; i < 5; i++) { p2[i] = (DlistNode *)malloc(sizeof(DlistNode)); p2[i]->data = i+10; // 헤드 노드의 오른쪽에 삽입 dinsert_node(&head_node2, p2[i]); } display(&head_node2); getchar(); phead_node = dconcat(&head_node, &head_node2); display(&head_node); getchar(); dremove_all(&head_node); display(&head_node); getchar(); }
728x90
728x90
'Computer Science > 자료구조' 카테고리의 다른 글
[C] 원형 연결 리스트(Circular Linked List) (0) | 2022.07.12 |
---|---|
[C] 단순 연결 리스트(Singly Linked List) (0) | 2022.07.12 |
[Python] 큐(Queue) (0) | 2022.07.01 |
[Python] 스택(Stack) (0) | 2022.07.01 |
[Python] 이진 탐색(Binary Search) (0) | 2022.06.29 |
[Python] 순차 탐색(Sequential Search) (0) | 2022.06.29 |
[Python] 원형 연결 리스트(Circular Linked List) (0) | 2022.06.22 |
[Python] 단순 연결 리스트(Singly Linked List) (0) | 2022.06.22 |