별의 공부 블로그 🧑🏻‍💻
728x90
728x170

이중 연결 리스트(Doubly Linked List)

 

- 응용 프로그램에서의 특정 노드에서 양방향으로 자유롭게 움직일 수 있는 리스트 구조.

- 하나의 노드가 선행 노드와 후속 노드에 대한 두 개의 링크를 가지는 리스트.

- 링크가 양방향이므로 양방향으로 검색이 가능해짐.

- 공간을 많이 차지하고 코드가 복잡해진다는 단점이 있음.

- 실제 응용에서는 이중 연결 리스트와 원형 연결 리스트를 혼합한 형태가 많이 사용됨.

- 헤드 노드(head node)라는 특별한 노드를 추가하는 경우가 많음.

- 헤드 노드는 데이터를 가지고 있지 않은 특별한 노드를 의미함.

cf) 헤드 포인터 : 리스트의 첫 번째 노드를 가리키는 포인터

- 헤드 노드가 존재하면 삽입, 삭제 알고리즘이 간편해짐.

- 이중 연결 리스트에서의 노드는 3개의 필드(왼쪽 링크 필드, 데이터 필드, 오른쪽 링크 필드)로 이루어져 있음.

- 링크 필드에는 포인터가 저장됨.

 

코드

// 이중 연결 리스트 (Doubly Linked List)

#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();
}

 

내용 출처 : C언어로 쉽게 풀어쓴 자료구조 (천인국 외 지음, 생능출판사)

728x90
그리드형(광고전용)

'Computer Science > Data Structure' 카테고리의 다른 글

[C] 그래프(Graph)  (0) 2017.06.19
[C] 정렬(Sorting)  (0) 2017.06.18
[C] 우선순위 큐(Priority Queue)  (0) 2017.06.17
[C] 트리(Tree)  (0) 2017.06.01
[C] 큐(Queue)  (0) 2017.05.23
[C] 스택(Stack)  (0) 2017.05.11
[C] 원형 연결 리스트(Circular Linked List)  (0) 2017.05.02
[C] 단순 연결 리스트(Singly Linked List)  (0) 2017.04.17
⚠️AdBlock이 감지되었습니다. 원할한 페이지 표시를 위해 AdBlock을 꺼주세요.⚠️


📖 Contents 📖