#include <stdio.h>
#include <stdlib.h>
#pragma warning (disable : 4996)
typedef struct DNode
{
int value;
struct DNode* prev;
struct DNode* next;
}DNode;
DNode* head = NULL;
DNode* tail = NULL;
DNode* createDnode(int data);
void insertFrontDNode(int data);
void insertTailDNode(int data);
void displayDNode();
void removeFirstDNode();
void removeTailDNode();
int getDNodeCount();
DNode* searchDNode(int target);
int removeTargetDNode(int target);
int removekthDNode(int k);
int main()
{
while (1)
{
printf("\n\n\t *** 이중 연결 리스트(Doubly Linked List)\n\n");
printf("=======================================================\n");
printf("1. 맨 앞 삽입\n");
printf("2. 맨 뒤 삽입\n");
printf("3. 앞에서부터 N번째 삽입\n");
printf("4. 오름차순 정렬 삽입\n");
printf("=======================================================\n");
printf("5. 맨 앞 삭제\n");
printf("6. 맨 뒤 삭제\n");
printf("7. 전체 노드 삭제\n");
printf("8. 특정 값 삭제\n");
printf("9. 앞에서부터 N번째 삭제\n");
printf("=======================================================\n");
printf("10. 이중 연결 리스트 출력(노드 순회)\n");
printf("11. 노드의 개수 구하기\n");
printf("12. 노드 검색\n");
printf(" 0. 프로그램 종료\n");
printf("=======================================================\n");
printf("\n메뉴 선택: ");
int choice;
scanf("%d", &choice);
int data, k;
switch (choice)
{
case 1:
printf("\n\n삽입할 정수 입력: ");
scanf("%d", &data);
insertFrontDNode(data);
break;
case 2:
printf("\n\n삽입할 정수 입력: ");
scanf("%d", &data);
insertTailDNode(data);
break;
case 3:
break;
case 4:
break;
case 5:
removeFirstDNode();
break;
case 6:
removeTailDNode();
break;
case 7:
break;
case 8:
printf("\n\n삭제할 값 입력: ");
scanf("%d", &data);
if (removeTargetDNode(data))
{
printf("\n\n\t\t삭제를 성공했습니다.\n");
}
else
{
printf("\n\n\t\t삭제를 실패했습니다.\n");
}
break;
case 9:
printf("\n\n몇 번째 데이터를 삭제하시겠습니까? ");
scanf("%d", &k);
if (removekthDNode(k))
{
printf("\n\n\t\t삭제를 성공했습니다.\n");
}
break;
case 10:
displayDNode();
break;
case 11:
printf("\n\n생성된 노드의 개수는 %d개 입니다.\n", getDNodeCount());
break;
case 12:
printf("\n\n검색 노드의 갑 입력 : ");
scanf("%d", &data);
if (searchDNode(data))
{
printf("\n\n\t\t검색한 노드는 존재 하지 않습니다. ");
}
else
{
printf("\n\n\t\t검색한 노드는 존재합니다. ");
}
searchDNode(data);
break;
case 0:
return 0;
}
printf("\n\n\t\t");
system("read");
}
return 0;
}
DNode* createDNode(int data)
{
DNode* newNode = (DNode*)malloc(sizeof(DNode));
newNode->value = data;
newNode->next = NULL;
newNode->prev = NULL;
return newNode;
}
void insertFrontDNode(int data)
{
DNode* newNode = createDNode(data);
if(head == NULL)
{
head = newNode;
tail = newNode;
printf("\n\n\t\t 노드 삽입(첫 노드로 연결)\n");
return;
}
newNode->next = head;
head->prev = newNode;
head = newNode;
printf("\n\n\t\t 노드 맨 앞 삽입(일반적인 경우)\n");
}
void insertTailDNode(int data)
{
DNode* newNode = createDNode(data);
if (head == NULL)
{
head = newNode;
tail = newNode;
printf("\n\n\t\t 노드 맨 뒤 삽입(첫 노드로 연결)\n");
return;
}
tail->next = newNode;
newNode -> prev = tail;
tail = newNode;
}
void displayDNode()
{
DNode* curNode;
if(head == NULL)
{
printf("\n\n\t\t연결리스트가 구성되지 않아 출력할 데이터가 없습니다.\n");
return;
}
system("clear");
printf("\n\nDoubly Linked List: ");
curNode = head;
while (curNode->next != NULL)
{
printf("%d => ", curNode->value);
curNode = curNode->next;
}
printf("%d\n", curNode->value);
}
void removeFirstDNode()
{
DNode* delNode;
if (head == NULL)
{
printf("\n\n\t\t연결리스트가 구성되지 않아 삭제할 데이터가 없습니다.\n");
return;
}
delNode = head;
head = head->next;
free(delNode);
if (head != NULL)
{
head->prev = NULL;
}
if (head == NULL)
{
tail = NULL;
}
}
void removeTailDNode()
{
DNode* delNode;
if (head == NULL)
{
printf("\n\n\t\t연결리스트가 구성되자 않아 삭제할 데이터가 없습니다.\n");
return;
}
delNode = tail;
tail = tail->prev;
free(delNode);
printf("\n\n\t\t마지막 노드가 제거됐습니다.\n");
if(tail != NULL)
{
tail->next = NULL;
}
if(tail == NULL)
{
head = NULL;
}
}
int getDNodeCount()
{
DNode* curNode;
int count;
if (head == NULL)
{
return 0;
}
count = 0;
curNode = head;
while (curNode != NULL)
{
++count;
curNode = curNode->next;
}
return count;
}
DNode* searchDNode(int target)
{
if (head == NULL)
{
return NULL;
}
DNode* curNode = head;
while (curNode)
{
if(curNode->value == target)
{
return curNode;
}
curNode = curNode->next;
}
return NULL;
}
int removeTargetDNode(int target)
{
if (head == NULL)
{
return 0;
}
if(head->value == target)
{
removeFirstDNode();
printf("\n\n\t\tcase1. 특정 값이 첫 노드인 경우 제거 성공\n");
return 1;
}
if(tail->value == target)
{
removeTailDNode();
printf("\n\n\t\tcase2. 특정 값이 마지막 노드인 경우 제거 성공\n");
return 1;
}
DNode* curNode = head;
while (curNode->next)
{
curNode = curNode->next;
if (curNode->value == target)
{
curNode->prev->next = curNode->next;
curNode->next->prev = curNode->prev;
free(curNode);
printf("\n\n\t\tcase 3.중간 값 제거 성공\n");
return 1;
}
}
return 0;
}
int removekthDNode(int k)
{
if (head == NULL)
{
return 0;
}
int nodeCount = getDNodeCount();
if(k < 1 || k > nodeCount)
{
printf("\n\n\t\t전달 받은 값은 삭제할 수 없는 수 입니다.\n");
printf("\t\t1 ~ %d 사이의 수를 입력해 주세요.\n", nodeCount);
return 0;
}
if(k == 1)
{
removeFirstDNode();
return 1;
}
if(k == nodeCount)
{
removeTailDNode();
printf("\n\n\t\tcase1. 마지막 노드 제거\n");
return 1;
}
if (k < nodeCount + 1 - k)
{
DNode* curNode = head;
for(int i = 1; i <= k - 1; i++)
{
curNode = curNode->next;
}
curNode->prev->next = curNode->next;
curNode->next->prev = curNode->prev;
free(curNode);
printf("\n\n\t\tcase3. 중간 값 제거");
return 1;
}
else
{
DNode* curNode = tail;
}
return 0;
}