c & c++/자료구조
연결형 리스트 구현
일상코더
2022. 8. 12. 01:39
1. 연결형 리스트(Linked List) 란?
하나의 개체를 이루는 노드가 연결되어 리스트를 이루는 "자료구조" 를 말한다.
노드에는 값을 담고 있는 '데이터'와 다음 노드를 가리키는 '링크' 정보를 저장하고 있는 것이 기본이다. '데이터'에는 숫자, 문자열, 또다른 연결리스트 등 다양한 형식을 가질 수 있다.
일반적으로 리스트의 맨 앞 노드를 헤드(Head), 맨 마지막 노드를 테일(Tail)이라고 한다.
2. 배열과의 차이점
배열과 연결리스트는 언뜻 비슷해 보이나, 차이점은 분명히 있다.
배열은 메모리의 연속한 위치에 저장되고, 연결 리스트는 각 노드가 임의의 위치에 저장된다.
또한 배열은 특정 원소를 지칭하는 것이 인덱스를 활용하는 등으로 간편하나(), 연결 리스트는 선형 탐색을 하듯 한 노드에서 다음 노드를 따라가야 한다().
하지만 배열보다 연결리스트는 비교적 삽입과 삭제가 용이하다.
3. 연결형 리스트 구현
#pragma once
//기능이 많지 않을때
template<typename T>
struct tNode
{
T Data;
tNode<T>* pPrev;
tNode<T>* pNext;
public:
tNode()
:Data(0)
,pPrev(nullptr)
,pNext(nullptr)
{
}
//생성자 오버로딩
tNode(T _Data, tNode<T>* _pPrev, tNode<T>* _pNext)
:Data(_Data)
,pPrev(_pPrev)
,pNext(_pNext)
{
}
};
// 클래스 리스트 리스트 클래스 생성
// 클래스 = 사용자 정의 자료형
template<typename T>
class cList
{
private:
tNode<T>* m_pHeadNode;
tNode<T>* m_pTailNode;
int m_iCount;
public:
//생성자 (초기화)
cList();
//소멸자
~cList();
public :
//멤버함수
void pushBack(const T& _Data);
void pushFront(const T& _Data);
};
template<typename T>
cList<T>::cList()
//이니셜라이저
:m_pHeadNode(nullptr)
,m_pTailNode(nullptr)
,m_iCount(0)
{
}
template<typename T>
cList<T>::~cList()
{
//첫번째 노드부터 다음주소를 받아서 하나씩 지워나감
//첫번재 노드를 가리키는 포인터 변수생성
tNode<T>* pDeleteNode = m_pHeadNode;
//반복문을 돌면서 첫번째 노드 부터 순차적으로 힙 메모리 영역 할당 해제
while (pDeleteNode) // pDeleteNode = 0 = nullptr일때까지 반복
{
//지우기 전에 현재 노드의 다음을 가리키는 노드주소를 변수로 받아놓음
tNode<T>* pNextNode = pDeleteNode->pNext;
delete(pDeleteNode); //할당해제
pDeleteNode = pNextNode; //pDeleteNode = 받아놓았던 다음노드
}
}
template<typename T>
void cList<T>::pushBack(const T& _Data)
{
// 노드 변수 선언 및 초기화, 생성자 오버로딩으로 코드가 간결해짐
tNode<T>* pNode = new tNode<T>(_Data, nullptr, nullptr);
// 데이터가 없을경우
if (m_pHeadNode == nullptr)
{
//기존에 가리키던 노드가 없었기 때문에 처음 들어온 노드를 가리킴
m_pHeadNode = pNode;
m_pTailNode = pNode;
}
// 기존에 데이터가 있을경우
else
{
//서로를 이어줌
m_pTailNode->pNext = pNode;
pNode->pPrev = m_pTailNode;
m_pTailNode = pNode;
}
// count 값 증가
++m_iCount;
}
template<typename T>
void cList<T>::pushFront(const T& _Data)
{
// 기존에 데이터가 있을경우 pushFront이기 때문에
// 원래 헤드 노드의 앞자리에 오기때문에 pNode->pNext = m_pHeadNode 이다
tNode<T>* pNode = new tNode<T>(_Data, nullptr, m_pHeadNode);
//서로 연결해줌
m_pHeadNode->pPrev = pNode;
m_pHeadNode = pNode;
//카운트 값 증가
++m_iCount;
}
4. 연결형 리스트 실행