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 |