빙수달 게임 개발 노트

[C++] 커서(Cursor)를 이용한 링크드 리스트로 학생 관리 프로그램 만들기 본문

Programming/알고리즘

[C++] 커서(Cursor)를 이용한 링크드 리스트로 학생 관리 프로그램 만들기

빙수달 2025. 9. 28. 15:58
# include <iostream>
# include <string>
# include <vector>

using namespace std;

const int MAX_STUDENTS = 10;

struct studentNode
{
	int id;
	string name;
	int next;		// 다음 노드의 '인덱스'를 저장
};

class studentBook
{
private:
	vector<studentNode> storage;
	int list_head;
	int free_head;

	// 새로운 노드를 할당받는 내부 함수
	int allocateNode()
	{
		if (free_head == -1) return -1;
		int newNodeIndex = free_head;	
		free_head = storage[free_head].next;
		return newNodeIndex;
	}

	// 사용이 끝난 노드를 가용 공간 리스트에 반납
	void deallocateNode(int index)
	{
		storage[index].next = free_head;
		free_head = index;
	}

public:
	studentBook();
	void insert(int id, string name);
	void remove(int id);
	void print();
	void search(int id);
};

int main()
{
	int num = 0;
	int ID = 0;
	string name = "";

	studentBook studentRecord;

	while (true)
	{
		cout << "1.삽입 2.출력 3.검색 4.삭제 5.종료" << endl;
		cout << "번호를 입력하세요 : ";
		cin >> num;

		switch (num)
		{
		case 1:
			cout << "학번 : "; cin >> ID;
			cout << "이름 : "; cin >> name;
			cout << endl;
			studentRecord.insert(ID, name);
			break;
		case 2:
			studentRecord.print();
			break;
		case 3:
			cout << "찾을 학생의 학번을 입력하시오.\n";
			cout << "학번 : "; cin >> ID;
			cout << endl;
			studentRecord.search(ID);
			break;
		case 4:
			cout << "삭제할 학생의 학번을 입력하시오.\n";
			cout << "학번 : "; cin >> ID;
			studentRecord.remove(ID);
			break;
		case 5:
			return 0;
		default:
			cout << "잘못된 번호입니다. 다시 입력해주세요.\n\n";
			break;
		}
	}
}

studentBook::studentBook()
{
	storage.resize(MAX_STUDENTS);
	list_head = -1;
	free_head = 0;

	for (int i = 0; i < MAX_STUDENTS - 1; ++i)
	{
		storage[i].next = i + 1;
	}
	storage[MAX_STUDENTS - 1].next = -1;
}

void studentBook::insert(int id, string name)
{
	int current = list_head;
	while (current != -1)
	{
		if (storage[current].id == id)
		{
			cout << "오류 : 이미 존재하는 학번입니다.\n\n";
			return;
		}
		current = storage[current].next;
	}

	int newNodeIndex = allocateNode();
	if (newNodeIndex == -1)
	{
		cout << "저장 공간이 가득 찼습니다.\n\n";
		return;
	}

	storage[newNodeIndex].id = id;
	storage[newNodeIndex].name = name;
	storage[newNodeIndex].next = list_head;
	list_head = newNodeIndex;

	cout << "학생이 추가되었습니다.\n\n";
}

void studentBook::remove(int id)
{
	if (list_head == -1)
	{
		cout << "등록된 학생이 없습니다.\n\n";
		return;
	}

	int current = list_head;
	int prev = -1;

	while (current != -1 && storage[current].id != id)
	{
		prev = current;
		current = storage[current].next;
	}

	if (current == -1)
	{
		cout << "해당 학번의 학생을 찾을 수 없습니다.\n\n";
		return;
	}

	// 노드 제거
	if (prev == -1)
	{
		list_head = storage[current].next;
	}
	else
	{
		storage[prev].next = storage[current].next;
	}

	deallocateNode(current);
	cout << "학생이 삭제되었습니다.\n\n";
}

void studentBook::print()
{
	if (list_head == -1)
	{
		cout << "등록된 학생이 없습니다.\n\n";
		return;
	}

	int current = list_head;
	while (current != -1)
	{
		cout << "학번 : " << storage[current].id << ", 이름 : " << storage[current].name << endl;
		current = storage[current].next;
	}
	cout << endl;
}

void studentBook::search(int id)
{
	if (list_head == -1)
	{
		cout << "등록된 학생이 없습니다.\n\n";
		return;
	}

	int current = list_head;
	while (current != -1)
	{
		if (storage[current].id == id)
		{
			cout << "학생을 찾았습니다.\n";
			cout << "학번 : " << storage[current].id << "\n이름 : " << storage[current].name << "\n\n";
			return;
		}
		current = storage[current].next;
	}
	cout << "해당 학번의 학생을 찾을 수 없습니다.\n\n";
}