Created
May 30, 2019 06:30
-
-
Save blood72/b73491670fe90a1b289236ce1d45a6e9 to your computer and use it in GitHub Desktop.
학창 시절에 만든 C언어 구조체 연결리스트 (int형 / char형 주석구분)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#pragma warning(disable:4996) //scanf 에러문 무시 | |
// #define BUF_SIZE 100 // char 형태 데이터 | |
// #define NAME_SIZE 20 // char 형태 데이터 | |
typedef struct Node{ | |
int data; // int 형태 데이터 | |
// char data[NAME_SIZE + BUF_SIZE]; // char 형태 데이터 | |
struct Node *link; | |
} Node; | |
void display(Node **head) // 입력과정을 검산하는 함수 | |
{ | |
Node *p = (*head)->link; // 헤드노드 이후부터 출력하기 위한 포인터 | |
while (p != NULL) // 연결리스트 끝까지 출력 | |
{ | |
printf("%d->", p->data); | |
p = p->link; | |
} | |
if ((*head)->link == NULL) // 헤드노드가 NULL이면 | |
printf("노드가 비어있습니다."); | |
printf("\n"); | |
} | |
void appendNode(Node **pointer, int data) | |
{ // 새로운 노드를 리스트에 연결시키는 함수 | |
// 첫번째 전달인자 Node * 다음에 전달되는 데이터 (int)를 연결시킴. | |
// 특정노드를 가리키는 포인터와 새 노드에 넣을 값을 인자로 받는다. | |
Node *p = *pointer; // 연결시킬 기준노드 | |
Node *new_node; // 새롭게 추가될 노드 | |
new_node = (Node *)malloc(sizeof(Node)); | |
new_node->data = data; // int 형태 | |
// strcpy(new_node->data, data); // char 형태 | |
// new_node를 p와 p->link 사이에 삽입한다. (p->link==NULL 포함) | |
new_node->link = p->link; | |
p->link = new_node; | |
} | |
void createNode(Node **head) | |
{ // 사용자가 원하는 노드 수 만큼 단순연결리스트를 만드는 함수. | |
// main함수에서 호출하며 리스트 헤드포인터의 포인터를 전달인자로 사용 | |
// 노드를 리스트에 연결할 때 appendNode함수를 호출하여 사용 | |
Node *p = *head; | |
int value = 0; // int 형태 | |
// char value[NAME_SIZE + BUF_SIZE]; // char 형태 | |
char cmd[12] = { 'y' }; // 초기값을 y로 주어 자동으로 반복문 진입 | |
while (cmd[0] != 'n') | |
{ | |
printf("데이터를 입력하세요 : "); | |
scanf("%d", &value); | |
appendNode(&p, value); // 노드 값 생성 및 연결 | |
fflush(stdin); // BUFFER표준입력영역정리 | |
printf("계속 진행하시겠습니까?(yes/no) : "); | |
scanf("%s", &cmd); | |
p = p->link; // 포인터를 1칸 전진시킴 | |
display(head); | |
} | |
} | |
Node *searchNode(Node **head, int value) | |
{ // 함수의 두번째 전달인자를 리스트에서 찾아 그 데이터의 이전 포인터를 리턴하고, | |
// 찾은 데이터를 가리키는 포인터를 첫번째 전달인자에 저장하는 함수. | |
// 값을 찾으면 가장 좌측부터 반환함. | |
Node *p = (*head)->link; | |
Node *prev = *head; | |
int pos = 1; // 검색된 노드의 위치변수 | |
display(head); | |
// 데이터를 찾으면 빠져나옴. | |
while ((p->link != NULL) && (p->data != value)) // int 형태 | |
// while ((p->link != NULL) && (strcmp(p->data, value))) // char 형태 | |
{ | |
prev = p; | |
p = p->link; | |
pos++; | |
} | |
if ((p->data == value)) // int 형태 | |
// if (!strcmp(p->data, value)) // char 형태 | |
{ | |
printf("찾는 값(%d)은 %d번째에 있습니다.\n", p->data, pos); | |
return prev; | |
} | |
else | |
{ | |
printf("찾는 값이 존재하지 않습니다. (검색한 값 : %d)\n", value); | |
return NULL; | |
} | |
} | |
void insertNode(Node **head) | |
{ // 삽입할 데이터와 위치를 입력받고 searchNode 함수를 이용하여 위치를 찾고 | |
// 새로운 노드를 appendNode 함수를 이용하여 리스트에 연결 | |
int value; // int 형태 | |
// char value[NAME_SIZE + BUF_SIZE]; // char 형태 | |
Node *p; | |
printf("삽입할 위치의 데이터를 입력하세요 : "); | |
scanf("%d", &value); | |
printf("기존 : "); | |
p = searchNode(head, value); // 노드검색함수를 호출해 p값에 저장한다. | |
if (p == NULL) // 이 때, p는 삽입할 위치의 이전 데이터를 가리킨다. | |
printf("찾는 값이 존재하지 않아 삽입할 수 없습니다.\n"); | |
else | |
{ // p != NULL일 때 삽입할 데이터위치(p->link)를 주고 appendNode호출 | |
fflush(stdin); //BUFFER표준입력영역정리 | |
printf("삽입할 데이터를 입력하세요 : "); | |
scanf("%d", &value); | |
appendNode(&(p->link), value); // 노드 값 생성 및 연결 | |
} | |
printf("결과 : "); | |
display(head); | |
} | |
void deleteNode(Node **head) | |
{ // searchNode함수를 이용하여 원하는 원소를 찾고 삭제하는 함수 | |
int value; // int 형태 | |
// char value[NAME_SIZE + BUF_SIZE]; // char 형태 | |
Node *p; | |
Node *pnext; | |
printf("삭제할 데이터를 입력하세요 : "); | |
scanf("%d", &value); | |
printf("기존 : "); | |
p = searchNode(head, value); // 노드검색함수를 호출해 p값에 저장한다. | |
if (p == NULL) // 이 때, p는 삽입할 위치의 이전 데이터를 가리킨다. | |
printf("찾는 값이 존재하지 않아 제거할 수 없습니다.\n"); | |
else | |
{ // p != NULL일 때 삭제할 데이터영역(pnext)을 삭제 | |
pnext = p->link; | |
p->link = pnext->link; | |
free(pnext); | |
} | |
printf("결과 : "); | |
display(head); | |
} | |
/* - 기본 원리 - | |
head_node는 searchNode함수에서 쓰이는 포인터 prev를 제대로 반환하기 위해 삽입했습니다. | |
헤드포인터가 head_node를 가리키고 있지만 실제 운영은 헤드노드부터 시작합니다. */ | |
int main(void) | |
{ | |
int command; // 스위치 조건문을 움직일 변수 | |
int value; // int 형태. 데이터 입력받을 변수 | |
// char value[NAME_SIZE + BUF_SIZE]; // char 형태. | |
Node *head_node = (Node *)malloc(sizeof(Node)); // 헤드노드 | |
Node *head = head_node; // ※헤드포인터는 헤드노드를 가리킨다. | |
head_node->link = NULL; | |
while (1) | |
{ | |
fflush(stdin); //BUFFER표준입력영역정리 | |
puts("\n0 : 종료, 1 : 생성, 2 : 검색, 3 : 삽입, 4 : 삭제"); | |
printf("위의 명령 중 하나를 입력하세요 : "); | |
scanf("%d", &command); | |
switch (command) | |
{ | |
case 1: // 노드를 생성한다. | |
if (head->link == NULL) //NULL일 때만 진입을 허용한다. | |
createNode(&head); //노드생성함수 호출 | |
else printf("이미 연결리스트가 존재합니다!\n");//"헤드포인터는 NULL이 아닙니다."); | |
break; | |
case 2: // 노드에 들어있는 값을 조사하여 위치를 출력한다. | |
if (head->link != NULL) //연결리스트가 존재할 때만 진입한다. | |
{ | |
printf("검색하고 싶은 값을 입력하세요 : "); | |
scanf("%d", &value); | |
printf("출력 : "); | |
searchNode(&head, value); //노드검색함수 호출 | |
} | |
else printf("연결리스트가 존재하지 않습니다!\n"); | |
break; | |
case 3: // 기존 데이터를 검색하고 해당하는 노드 뒤에 삽입할 데이터를 입력받고 연결시킨다. | |
if (head->link != NULL) //연결리스트가 존재할 때만 진입한다. | |
insertNode(&head); //노드삽입함수 호출 | |
else printf("연결리스트가 존재하지 않습니다!\n"); | |
break; | |
case 4: // 데이터를 검색해 해당하는 값을 가진 가장 좌측의 노드를 삭제한다. | |
if (head->link != NULL) //연결리스트가 존재할 때만 진입한다. | |
deleteNode(&head); //노드삭제함수 호출 | |
else printf("연결리스트가 존재하지 않습니다!\n"); | |
break; | |
case 0: | |
return 0; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment