티스토리 뷰




이번에 프로젝트 하면서 알게된 내용을 정리해봅니다!




연결 리스트(Linked List)란?




<출처 : https://www.sitesbay.com/data-structure/c-linked-list>


연결 리스트(Linked List)란, 자료구조의 일종으로 말 그대로 어떤 데이터를 저장할 때 그다음 순서의 자료가 있는 위치를 데이터에 포함하는 방식으로 자료를 저장합니다.


배열이 자료에 순번을 메겨 맞춘다면, 연결 리스트는 자료의 순서에 맞춰 연결합니다. 그렇기 때문에 배열과는 달리 새로운 자료, 노드를 뒤에 연결하거나 중간에 끼워 넣는 것이 쉽습니다. 그러나 배열에는 자료마다 고유의 번호가 있어서 사용자가 원하는 특정한 자료를 불러내기가 편한 반면에 연결 리스트는 자료마다 고유의 번호가 없어서 특정한 자료, 노드를 불러내기가 어렵다는 점이 있습니다.


단순 연결 리스트는 다음 노드에 대한 참조만을 가진 가장 단순한 연결 리스트입니다. 제일 맨 끝에 있는 노드를 찾으려면 리스트의 맨 끝까지 가야 하므로 마지막 노드를 가리키는 참조를 가지는 형태도 있습니다.


단순 연결 리스트는 Head 노드를 참조하는 주소를 잃어버린다면, 리스트 전체를 못 쓰게 되는 단점이 있습니다. 가장 단순한 자료구조이지만, 안전한 자료구조는 아니라는 것입니다.




제가 이번에 회원 관리 프로그램을 만들었는데,


단순 연결 리스트를 이용하여 회원 조회, 회원 리스트, 회원 등록, 회원 수정, 회원 삭제의 기능을 구현했고,


파일 입출력을 이용하여 txt 파일에 자료를 저장하고 불러오는 기능을 구현했습니다!


아래는 프로젝트의 소스코드입니다.




#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <Windows.h>

typedef struct Member_recruitment {   // 연결 리스트의 노드 구조체
	char MemberName[12];
	char MemberAge[4];
	char MemberSex[8];
	char MemberType[2];
	struct Member_recruitment *next;   // 다음 노드의 주소를 저장할 포인터
}Member_recruitment;

Member_recruitment *FirstMember = NULL;   // 첫번째 노드

Member_recruitment * makenode()
{
	Member_recruitment *tmp = (Member_recruitment *)malloc(sizeof(Member_recruitment));   // 알맞는 공간 생성
	tmp->next = NULL;
	return tmp;
}

void AddMember(Member_recruitment **head, char MemberName[], char MemberAge[], char MemberSex[], char MemberType[]) {
	if (!*head)
	{
		*head = makenode();
		strcpy((*head)->MemberName, MemberName);
		strcpy((*head)->MemberAge, MemberAge);
		strcpy((*head)->MemberSex, MemberSex);
		strcpy((*head)->MemberType, MemberType);
		return;
	}
	AddMember(&(*head)->next, MemberName, MemberAge, MemberSex, MemberType);
}

void MemberNameDelete(char MemberName[]) {   // 멤버 삭제 함수
	int i;
	Member_recruitment *temp;
	Member_recruitment *prev;
	temp = FirstMember;
	if (strcmp(temp->MemberName, MemberName) == 0) {
		FirstMember = temp->next;
		free(temp);
	}
	else {
		for (i = 0; strcmp(temp->MemberName, MemberName) != 0; ++i) {
			temp = temp->next;
			if (i != 0) {
				prev = prev->next;
			}if (i == 1) {
				prev = FirstMember;
			}
		}
		prev->next = temp->next;
		free(temp);
	}
}

void MemberList() {   // 멤버 리스트를 출력해주는 함수
	system("cls");
	int i;
	if (FirstMember == NULL) {
		printf("회원이 존재하지 않습니다. \n");
		return;
	}
	else {
		Member_recruitment *temp = FirstMember;
		for (i = 1; temp != NULL; ++i) {
			printf("──────");
			printf("NO : %d \n", i);
			printf("Name : %s \n", temp->MemberName);
			printf("Age : %s \n", temp->MemberAge);
			printf("Sex : %s \n", temp->MemberSex);
			printf("Class : %s \n", temp->MemberType);
			printf("──────");
			temp = temp->next;
		}
	}
	_getch();
}

Member_recruitment *MemberSearch() {   // 원하는 정보로 멤버를 찾는 함수
	int i;
	int input;
	int inputNumber;
	int inputSex;
	int inputName;
	int inputClass;
	Member_recruitment *temp;
	temp = FirstMember;
	printf("검색을 진행할 모드를 선택해주세요 : \n");
	printf("1. 고유번호 \n");
	printf("2. 성별 \n");
	printf("3. 이름 \n");
	printf("4. 클래스 \n");
	input = _getch();
	printf("\n");
	switch (input) {
	case '1':
		printf("찾으실 회원의 고유번호를 입력해주세요 : \n");
		scanf("%d", &inputNumber);
		for (i = 1; i < inputNumber; ++i) {
			temp = temp->next;
		}
		if (temp == NULL) {
			printf("Empty Set");
			return 0;
		}
		system("cls");
		for (i = 1; temp != NULL; ++i) {
			Member_recruitment *temp = FirstMember;
			printf("──────");
			printf("NO : %d \n", i);
			printf("Name : %s \n", temp->MemberName);
			printf("Age : %s \n", temp->MemberAge);
			printf("Sex : %s \n", temp->MemberSex);
			printf("Class : %s \n", temp->MemberType);
			printf("──────");
			temp = temp->next;
			break;
		}
	case '2':
		printf("찾으실 회원의 성별을 입력해주세요 : \n");
		scanf("%d", &inputSex);
		for (i = 1; i < inputSex; ++i) {
			temp = temp->next;
		}
		if (temp == NULL) {
			printf("Empty Set");
			return 0;
		}
		system("cls");
		for (i = 1; temp != NULL; ++i) {
			Member_recruitment *temp = FirstMember;
			printf("──────");
			printf("NO : %d \n", i);
			printf("Name : %s \n", temp->MemberName);
			printf("Age : %s \n", temp->MemberAge);
			printf("Sex : %s \n", temp->MemberSex);
			printf("Class : %s \n", temp->MemberType);
			printf("──────");
			temp = temp->next;
			break;
		}
	case '3':
		printf("찾으실 회원의 이름을 입력해주세요 : \n");
		scanf("%d", &inputName);
		for (i = 1; i < inputName; ++i) {
			temp = temp->next;
		}
		if (temp == NULL) {
			printf("Empty Set");
			return 0;
		}
		system("cls");
		for (i = 1; temp != NULL; ++i) {
			Member_recruitment *temp = FirstMember;
			printf("──────");
			printf("NO : %d \n", i);
			printf("Name : %s \n", temp->MemberName);
			printf("Age : %s \n", temp->MemberAge);
			printf("Sex : %s \n", temp->MemberSex);
			printf("Class : %s \n", temp->MemberType);
			printf("──────");
			temp = temp->next;
			_getch();
			break;
		}
	case '4':
		printf("찾으실 회원의 클래스를 입력해주세요 : \n");
		scanf("%d", &inputClass);
		for (i = 1; i < inputClass; ++i) {
			temp = temp->next;
		}
		if (temp == NULL) {
			printf("Empty Set");
			return 0;
		}
		system("cls");
		for (i = 1; temp != NULL; ++i) {
			Member_recruitment *temp = FirstMember;
			printf("──────");
			printf("NO : %d \n", i);
			printf("Name : %s \n", temp->MemberName);
			printf("Age : %s \n", temp->MemberAge);
			printf("Sex : %s \n", temp->MemberSex);
			printf("Class : %s \n", temp->MemberType);
			printf("──────");
			temp = temp->next;
			_getch();
			break;
		}
	default:
		break;

	}
}

void MemberEdit() {   // 멤버의 원하는 정보를 수정해주는 함수
	int i;
	int input = 0;
	int inputNumber = 0;
	char EditName[50];
	char EditAge[10];
	char EditSex[8];
	char EditType[1];
	Member_recruitment *temp;
	temp = FirstMember;
	printf("수정하실 회원의 고유번호를 입력해주세요 : ");
	scanf("%d", &inputNumber);
	for (i = 1; i < inputNumber; ++i) {
		temp = temp->next;
	}
	if (temp == NULL) {
		printf("Empty Set");
		return 0;
	}
	printf("수정할 사항 (1. Name 2. Age 3. Sex 4. Class) \n");
	printf("입력 : ");
	input = _getche();
	switch (input) {
	case '1':
		printf("\n");
		printf("변경하실 이름을 입력해주세요 : ");
		scanf("%s", &EditName);
		strcpy((temp->MemberName), EditName);
		temp = temp->next;
		_getch();
		break;
	case '2':
		printf("\n");
		printf("변경하실 나이를 입력해주세요 : ");
		scanf("%s", &EditAge);
		strcpy((temp->MemberAge), EditAge);
		temp = temp->next;
		_getch();
		break;
	case '3':
		printf("\n");
		printf("변경하실 성별을 입력해주세요 : ");
		scanf("%s", &EditSex);
		strcpy((temp->MemberAge), EditSex);
		temp = temp->next;
		_getch();
		break;
	case '4':
		printf("\n");
		printf("변경하실 타입을 입력해주세요 : ");
		scanf("%s", &EditSex);
		strcpy((temp->MemberType), EditType);
		temp = temp->next;
		_getch();
		break;
	}
}

void TxtLoad() {   // MemberList.txt 파일에서 정보를 불러오는 함수
	FILE *load = fopen("MemberList.txt", "rt");
	if (load != NULL) {
		Member_recruitment *MidNode = NULL;
		int loadfp;
		while (feof(load) == 0) {
			MidNode = (Member_recruitment *)malloc(sizeof(Member_recruitment));
			MidNode->next = NULL;
			fscanf(load, "%s %s %s %s\n", &MidNode->MemberName, &MidNode->MemberAge, &MidNode->MemberSex, &MidNode->MemberType);

			if (FirstMember == NULL) {
				FirstMember = MidNode;
			}
			else {
				Member_recruitment *temp = FirstMember;
				while (temp->next != NULL) {
					temp = temp->next;
				}
				temp->next = MidNode;
			}
		}
	}
}

void Exit() {   // 프로그램이 종료될 때 MemberList.txt에 새로운 값들을 저장해주는 함수
	FILE * save = fopen("MemberList.txt", "wt");
	if (FirstMember != NULL) {
		while (FirstMember->next != NULL) {
			Member_recruitment *al = FirstMember;
			fprintf(save, "%s %s %s %s\n", al->MemberName, al->MemberAge, al->MemberSex, al->MemberType);
			FirstMember = FirstMember->next;
		}
		fprintf(save, "%s %s %s %s", FirstMember->MemberName, FirstMember->MemberAge, FirstMember->MemberSex, FirstMember->MemberType);
		free(FirstMember);
	}
}

void main() {   // main
	int input_count;
	char input_MemberName[10];
	char input_MemberAge[3];
	char input_MemberSex[8];
	char input_MemberType[2];
	TxtLoad();
	while (1) {
		system("mode con:cols=50lines=20");
		system("cls");
		printf("※ Member management ※ \n\n");
		printf("1. ADD \n");
		printf("2. List \n");
		printf("3. Search \n");
		printf("4. Modify \n");
		printf("5. Delete \n");
		printf("6. Exit \n");
		char input;
		int re;
		input = _getche();
		printf("\n");
		switch (input) {
		case '1':
			printf("이름을 입력하세요 : ");
			gets(input_MemberName);
			printf("나이를 입력하세요 : ");
			gets(input_MemberAge);
			printf("성별을 입력하세요. (남=Male 여=Female) : ");
			gets(input_MemberSex);
			printf("타입을 입력하세요. (A,B,C) : ");
			gets(input_MemberType);
			input_count = 0;
			AddMember(&FirstMember, input_MemberName, input_MemberAge, input_MemberSex, input_MemberType);
			break;
		case '2':
			MemberList();
			break;
		case '3':
			MemberSearch();
			break;
		case '4':
			MemberEdit();
			break;
		case '5':
			printf("삭제하실 회원의 이름을 입력하세요 : ");
			gets(input_MemberName);
			MemberNameDelete(input_MemberName);
			break;
		case '6':
			Exit();
			system("pause>null");
			exit(0);
		default:
			printf("다시 입력하세요. \n");
			_getch();
			break;
		}
	}
}





댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함