티스토리 뷰
Develop Story/Data Structure & Algorithm
<뇌를 자극하는 알고리즘 #2>: 이중 연결 리스트(DLL) 퀴즈풀이
wisecow 2017. 7. 22. 00:10
Vitamin Quiz
문제) 더블 링크드 리스트를 역순으로 출력하는 함수를 작성해라. 원형은 다음과 같다.
void PrintReverse(Node *head);
풀이 // 이 글은 드래그 및 복붙이 안되므로, 최하단에 첨부한 문제풀이 소스코드를 따로 받아보시길 바랍니다.
/* 교재의 소스 코드 중, 문제풀이에 꼭 필요한 소스코드만 사용했습니다. 또한 데브맷이 임의적으로 변수의 이름과 함수의 이름을 재설정해줬습니다. 가독성과 의미를 고려한 결정이었습니다. 헤더파일 분할 없이 데브맷 풀이.c 에 코드를 담았으며 교재의 원본소스와 문제풀이 답안을 포함한 자체제작 소스 둘 다 최하단에 첨부해놨습니다. */
맨 마지막에 정의되어 있는 printReverse 함수를 집중적으로 살펴보도록 하자. 나머지는 교재의 소스코드와 별반 차이가 없다. 핵심 개념 (오른쪽 끝의 노드에 접근했다가 다시 왼쪽 끝 노드로 옮겨가면서 데이터를 출력한다.)이 중요한 것이니까.
/************************************************* ** 이중 연결 리스트 (DDL Vitamin Quiz 문제풀이 포함 소스코드) *************************************************/ #include <stdio.h> #include <stdlib.h> typedef int element; typedef struct DNode { element data; struct DNode *prev, *next; } DNode; DNode* createDNode(element data); void appendDNode(DNode **head, DNode *newNode); DNode* getDNodeAt(DNode *head, int location); void removeDNode(DNode **head, DNode *remove); void insertAfter(DNode *current, DNode *newNode); int getDNodeCount(DNode *head); void printReverse(DNode *head); void main() { int i, count; DNode *list, *newNode, *current; i = count = 0; list = newNode = current = NULL; for (i = 0; i < 5; i++) { newNode = createDNode(i); appendDNode(&list, newNode); } count = getDNodeCount(list); for (i = 0; i < count; i++) { current = getDNodeAt(list, i); printf("list[%d]: %d\n", i, current->data); } // 역순으로 출력한다. printReverse(list); // 모든 노드를 메모리에서 제거 printf("\ndelete list...\n"); count = getDNodeCount(list); for (i = 0; i < count; i++) { // 맨 앞의 노드가 없어지고 새롭게 head노드가 갱신되는 원리를 사용 current = getDNodeAt(list, 0); // 결국 마지막에 존재하던 노드까지 사라졌다면 // getDNodeAt 의 반환 결과는 NULL일 것이다. if (current != NULL) { removeDNode(&list, current); } } } DNode* createDNode(element data) { DNode *newDNode = (DNode *)malloc(sizeof(DNode)); if (!newDNode) { fprintf(stderr, "동적할당오류"); exit(EXIT_FAILURE); } newDNode->data = data; newDNode->prev = newDNode->next = NULL; return newDNode; } void appendDNode(DNode **head, DNode *newNode) { if (*head == NULL) { *head = newNode; } else { DNode *tail = *head; while (tail->next != NULL) tail = tail->next; tail->next = newNode; newNode->prev = tail; } } DNode* getDNodeAt(DNode *head, int location) { while (head->next != NULL && (--location) >= 0) { head = head->next; } return head; } void removeDNode(DNode **head, DNode *remove) { if (*head == remove) { *head = (*head)->next; (*head)->prev == NULL; } else { remove->prev->next = remove->next; if(remove->next != NULL) remove->next->prev = remove->prev; } remove->prev = remove->next = NULL; free(remove); } void insertAfter(DNode *current, DNode *newNode) { newNode->next = current->next; newNode->prev = current; if (current->next != NULL) current->next->prev = newNode; current->next = newNode; } int getDNodeCount(DNode *head) { unsigned int count = 0; while (head != NULL) { count++; head = head->next; } return count; } void printReverse(DNode *head) { printf("역순으로 출력을 시작합니다.\n"); int index = 0; // 예외상황: 노드가 하나 뿐이었을 때 if (head->next == NULL) printf("list[%d]: %d\n", index, head->data); // 정상: 노드가 2개 이상 존재할 때 while (head->next != NULL) { // 노드의 끝까지 index를 더해가며 접근한다. index++; head = head->next; } // while문을 빠져나왔다면 성공적으로 마지막 노드에 접근을 한 것이다. if (head->next == NULL) { // 다시 첫 노드로 되돌아가는 작업을 하는데 이 때의 조건은 head != NULL 이다. while (head != NULL) { // 첫 노드의 전에노드는 NULL일 것이므로, 조건을 이렇게 줬다. printf("list[%d]: %d\n", index, head->data); head = head->prev; // 이전 노드로 이동한다. index--; // 인덱스 값을 하나씩 감소시킨다. } } } /************************************************* ** End Line *************************************************/
'Develop Story > Data Structure & Algorithm' 카테고리의 다른 글
<뇌를 자극하는 알고리즘 #4>: 트리(LCRSTree) 퀴즈풀이 (0) | 2017.07.22 |
---|---|
<뇌를 자극하는 알고리즘 #3>: 배열로 구현된 스택(AS) 퀴즈풀이 (0) | 2017.07.22 |
<뇌를 자극하는 알고리즘 #1>: 단일 연결 리스트(SLL) 퀴즈풀이 (0) | 2017.07.21 |
<선택 정렬 및 이진 탐색 알고리즘> #Selection sort #Binary search (0) | 2017.07.18 |
<이진 탐색트리> 탐색, 삽입, 삭제 알고리즘 및 시간복잡도 분석 (2) | 2017.07.15 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday