공부 중 메모/수업 예제 (KGCA)

LinkedList 양방향 리스트 예제 <Head가 포인터가 아닌 리스트>

라이피 (Lypi) 2018. 7. 23. 18:55
반응형
//////////////////////////////////////////////////////////////
// 헤드노드(g_pNodeHead)부터 실제 데이터를 저장하는 이중연결리스트
// 리스트가 비어있으면 새로운 데이터를 헤드로 저장한다.
// InsertLink_H : 새로운 노드가 헤드의 Next에 연결되는 전위 연결.
// InsertLink_T : 새로운 노드가 테일의 Next에 연결되는 후위 연결.
//////////////////////////////////////////////////////////////


header.h

#pragma once

#include <conio.h>
#include <time.h> // time()

#include <iostream> // +<cstdio> +<cstdlib> 
#include <fstream>
#include <string>

using std::cout;
using std::cin;
using std::endl;

using std::getline;

using std::ifstream;
using std::ofstream;

using std::string;

dList.h

#pragma once
#include "header.h"

//////////////////////////////////////////////////////////////
// 헤드노드(g_pNodeHead)부터 실제 데이터를 저장하는 이중연결리스트
// 리스트가 비어있으면 새로운 데이터를 헤드로 저장한다.
// InsertLink_H : 새로운 노드가 헤드의 Next에 연결되는 전위 연결.
// InsertLink_T : 새로운 노드가 테일의 Next에 연결되는 후위 연결.
//////////////////////////////////////////////////////////////

class dList
{
	struct data {
		string	m_strName;
		int		m_iAge;

		data*   pPrev;
		data*   pNext;
	};

	data*   pHead;
	data*   pTail;

	int     m_iCount;

public:

	//bool(*process) ();
	//bool    Excute();

	dList();

	bool    CreateData();            // 새로운 데이터를 기록한 파일을 만든다.

	void    AddLink_H(data* pStu);            // pHead 노드 앞에 삽입한다.
	void    AddLink_T(data* pStu);            // pTail 노드 뒤에 삽입한다.

	void    DeleteList();                     // 전체 연결리스트 삭제

	bool    DataRead_H();                     // 파일로부터 데이터를 읽어 전위 연결리스트를 만든다.
	bool    DataRead_T();                     // 파일로부터 데이터를 읽어 후위 연결리스트를 만든다.

	bool    PrintData(data* pStu);            // data* pStu를 출력한다.
	bool    PrintAllData();                   // 전체 연결리스트를 출력한다.

	void    MenuClear();

	~dList();
};

dList.cpp

#pragma once
#include "dList.h"

dList::dList()
{
	pHead = nullptr;
	pTail = nullptr;

	m_iCount = 0;
}

bool    dList::CreateData()
{
	DeleteList();

	srand((unsigned int)time(NULL));
	
	ofstream os;
	os.open("data.txt");

	int count = 5;

	if (os.is_open()) {
		os << count << endl;

		for (int iCnt = 0; iCnt < count; iCnt++) {
			string name = "";
			name += 65 + rand() % 26; //A(65), a(97)
			name += 65 + rand() % 26;
			name += 65 + rand() % 26;

			os << name << endl << 20 + rand() % 10 << endl;
		}

		return true;
	}
	else {
		cout << "파일 생성 실패" << endl;
		return false;
	}

}// 새로운 데이터를 기록한 파일을 만든다.
		
void    dList::AddLink_H(data* pStu) 
{
	pStu->pPrev = nullptr;
	pStu->pNext = nullptr;

	if (pHead == nullptr) {
		pTail = pStu;
	}
	else {
		pStu->pNext = pHead;
		pHead->pPrev = pStu;
	}

	pHead = pStu;
} // pHead 노드 앞에 추가한다.

void    dList::AddLink_T(data* pStu) 
{
	pStu->pPrev = nullptr;
	pStu->pNext = nullptr;

	if (pHead == nullptr) {
		pHead = pStu;
	}
	else {
		pStu->pPrev = pTail;
		pTail->pNext = pStu;
	}
	pTail = pStu;
}
// pTail 노드 뒤에 추가한다.
		
void    dList::DeleteList()
{
	if (pHead == nullptr) {
		return;
	}
	else {
		data* pData = pHead;

		while (pData->pNext) { // == (pData->pNext != nullptr) 
			data* delData = pData->pNext;
			pData->pNext = delData->pNext;
			delete delData;
		}
		delete pHead;

		m_iCount = 0;
		pHead = nullptr;
		pTail = nullptr;
	}
}

bool    dList::DataRead_H()
{
	DeleteList();

	ifstream is;
	is.open("data.txt");

	if (is.is_open()) {
		is >> m_iCount;

		for (int iCnt = 0; iCnt < m_iCount; iCnt++) {

			data* pData = new data;

			is >> pData->m_strName;
			is >> pData->m_iAge;

			AddLink_H(pData);
		}
		return true;
	}
	else {
		cout << "파일 열기 실패" << endl;
		return false;
	}

}// 파일로부터 데이터를 읽어 전위 연결리스트를 만든다.

bool    dList::DataRead_T()
{
	DeleteList();

	ifstream is;
	is.open("data.txt");

	if (is.is_open()) {
		is >> m_iCount;

		for (int iCnt = 0; iCnt < m_iCount; iCnt++) {

			data* pData = new data;

			is >> pData->m_strName;
			is >> pData->m_iAge;

			AddLink_T(pData);
		}
		return true;
	}
	else {
		cout << "파일 열기 실패" << endl;
		return false;
	}

}// 파일로부터 데이터를 읽어 후위 연결리스트를 만든다.


bool    dList::PrintData(data* pStu)
{
	if (pStu == nullptr)
	{
		cout << "데이터 없음" << endl;
		return false;
	}
	else {
		cout << "이름 : " << pStu->m_strName << ", 나이 : " << pStu->m_iAge << endl;
		return true;
	}

}// Data* pStu를 출력한다.

bool    dList::PrintAllData()
{
	data* pData = pHead;

	while (pData) {
		PrintData(pData);
		pData = pData->pNext;
	}
	return true;
}// 전체 연결리스트를 출력한다.

void    dList::MenuClear()
{
	system("cls");
	printf("===================================\n");
	printf("====   성적 관리 프로그램      ====\n");
	printf("===================================\n");
}



dList::~dList()
{
	DeleteList();
}

main.cpp

#include "dList.h"

int main()
{
	dList a;

	while (true) {
		int iSelect = 0;

		cout << "select number" << endl;
		cout << "0 : 파일에 데이터 새로 쓰기" << endl;
		cout << "1 : 전위 연결 리스트 만들기" << endl;
		cout << "2 : 후위 연결 리스트 만들기" << endl;
		cout << "3 : 리스트 전체 출력하기" << endl;
		cout << "그외 : 종료" << endl;
		cin >> iSelect;

		bool (dList::*process)();

		switch (iSelect) {
		case 0:
			process = &dList::CreateData;
			break;

		case 1:
			process = &dList::DataRead_H;
			break;

		case 2:
			process = &dList::DataRead_T;
			break;

		case 3:
			process = &dList::PrintAllData;
			break;

		default:
			return 0;
		}

		a.MenuClear();
		(a.*process)();
	}

}


반응형