ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 연결 자료구조 - 원형 연결 리스트(Circular Linked List)
    프로그래밍 기초/자료구조 2020. 11. 11. 08:45

      원형 연결 리스트 

    원형 연결 리스트는 마지막 노드가 처음 노드를 가리키는 환형 구조가 되는 연결 리스트로 단일 연결 리스트와 이중 연결 리스트에 모두 적용이 가능하다.

     

    - 단일 연결 리스트 적용 예

     

    - 이중 연결 리스트 적용 예

     

    ※ 리스트 순회 시 다음 노드가 첫 노드인 경우 순회를 종료하면 된다.

     

      원형 연결 리스트 구현 준비 

    원형 연결 리스트는 단일 연결 리스트 혹은 이중 연결 리스트의 삽입과 삭제, 기능 연산에서 리스트의 끝을 확인하는 방식을 변경하여 구현할 수 있다.

     

    단일 연결 리스트 혹은 이중 연결 리스트를 원형 연결 리스트로 변경하기 위해 다음의 메서드를 수정해야 한다.

     

    • 생성자
      • 복사 생성자
    • 메서드 
      • 데이터 삽입 메서드
      • 데이터 삭제 메서드
      • 기능 메서드

     

      단일 원형 연결 리스트 구현 

    SinglyLinkedList를 변형하여 단일 원형 연결 리스트를 구현한다.

     

    SinglyCircularLinkedList.h

    #pragma once
    #include <xutility>
    #include <iostream>
    
    struct SinglyCircularLinkedListNode
    {
    	SinglyCircularLinkedListNode() {}
    	SinglyCircularLinkedListNode(int value) { m_data = value; }
    
    	int m_data{ 0 };
    	SinglyCircularLinkedListNode* m_next{ nullptr };
    };
    
    class SinglyCircularLinkedList
    {
    public:
    #pragma region 생성자
    	SinglyCircularLinkedList();
    	SinglyCircularLinkedList(const SinglyCircularLinkedList& other);
    	~SinglyCircularLinkedList();
    #pragma endregion
    
    #pragma region 속성
    	const size_t Count() { return m_count; }
    	SinglyCircularLinkedListNode& Front() { return *m_head; }
    #pragma endregion
    
    #pragma region 메서드
    	void Add(int value);
    	void Add(SinglyCircularLinkedListNode* node);
    	void Insert(size_t index, int value);
    	void Insert(size_t index, SinglyCircularLinkedListNode* node);
    
    	bool Remove(int value);
    	void Remove(const SinglyCircularLinkedListNode* node);
    	void Clear();
    
    	bool Contains(int value);
    	bool Contains(const SinglyCircularLinkedListNode* node);
    	SinglyCircularLinkedListNode* Find(int value);
    	SinglyCircularLinkedListNode* FindLast(int value);
    #pragma endregion
    
    private:
    #pragma region Class Util
    	SinglyCircularLinkedListNode* PopNode(int value);
    	void PushNode(SinglyCircularLinkedListNode* node);
    
    	void UpdateHead(SinglyCircularLinkedListNode* node);
    #pragma endregion
    	
    private:
    #pragma region 변수
    	size_t m_count;
    	SinglyCircularLinkedListNode* m_head;
    	SinglyCircularLinkedListNode* m_free;
    #pragma endregion
    };

     

    생성자, 소멸자 구현

    기본 생성자와 SinglyCircularLinkedList를 인자로 받는 복사 생성자를 구현한다.

     

    SinglyCircularLinkedList.cpp

    /// <summary>
    /// 비어있는 SinglyCircularLinkedList를 생성한다.
    /// </summary>
    SinglyCircularLinkedList::SinglyCircularLinkedList()
    	: m_count(0), m_head(nullptr), m_free(nullptr)
    {
    }
    
    /// <summary>
    /// 다른 SinglyCircularLinkedList가 가지고 있는 노드를 복사해 SinglyCircularLinkedList를 생성한다.
    /// </summary>
    /// <param name="other">기준이 될 SinglyCircularLinkedList</param>
    SinglyCircularLinkedList::SinglyCircularLinkedList(const SinglyCircularLinkedList& other)
    	: m_count(other.m_count), m_head(nullptr), m_free(nullptr)
    {
    	if (other.m_head == nullptr)
    	{
    		return;
    	}
    
    	SinglyCircularLinkedListNode* curNode{ other.m_head };
    	SinglyCircularLinkedListNode* prevNode{ PopNode(curNode->m_data) };
    
    	m_head = prevNode;
    	curNode = curNode->m_next;
    
    	while (curNode->m_next != other.m_head)
    	{
    		SinglyCircularLinkedListNode* newNode{ PopNode(curNode->m_data) };
    		prevNode->m_next = newNode;
    		prevNode = newNode;
    		curNode = curNode->m_next;
    	}
    }
    
    /// <summary>
    /// 메모리 누수를 막기 위해 동적 생성한 노드들을 제거한다.
    /// </summary>
    SinglyCircularLinkedList::~SinglyCircularLinkedList()
    {
    	if (m_head != nullptr)
    	{
    		SinglyCircularLinkedListNode* head{ m_head };
    		do
    		{
    			SinglyCircularLinkedListNode* curNode{ m_head };
    			m_head = m_head->m_next;
    			delete curNode;
    		} while (m_head != head);
    	}
    
    	while (m_free != nullptr)
    	{
    		SinglyCircularLinkedListNode* curNode{ m_free };
    		m_free = m_free->m_next;
    		delete curNode;
    	}
    }

     

    데이터 삽입 메서드 구현

    데이터 삽입 연산에 필요한 메서드들을 구현한다.

     

    SinglyCircularLinkedList.cpp

    /// <summary>
    /// SinglyCircularLinkedList의 시작 위치에 지정한 값이 포함된 새 노드를 추가한다.
    /// </summary>
    /// <param name="value">추가할 값</param>
    void SinglyCircularLinkedList::Add(int value)
    {
    	SinglyCircularLinkedListNode* newNode{ PopNode(value) };
    	Add(newNode);
    }
    
    /// <summary>
    /// SinglyCircularLinkedList의 시작 위치에 지정한 노드를 추가한다.
    /// </summary>
    /// <param name="node">추가할 새 노드</param>
    void SinglyCircularLinkedList::Add(SinglyCircularLinkedListNode* node)
    {
    	if (node == nullptr || node->m_next != nullptr)
    	{
    		throw std::invalid_argument("node");
    	}
    
    	node->m_next = m_head;
    
    	UpdateHead(node);
    
    	m_count++;
    }
    
    /// <summary>
    /// SinglyCircularLinkedList의 지정한 인덱스에 해당하는 위치에 지정한 값이 포함된 새 노드를 추가한다.
    /// </summary>
    /// <param name="index">값을 추가할 인덱스</param>
    /// <param name="value">추가할 값</param>
    void SinglyCircularLinkedList::Insert(size_t index, int value)
    {
    	SinglyCircularLinkedListNode* newNode{ PopNode(value) };
    	Insert(index, newNode);
    }
    
    /// <summary>
    /// SinglyCircularLinkedList의 지정한 인덱스에 해당하는 위치에 지정된 노드를 추가한다.
    /// </summary>
    /// <param name="index">새 노드를 추가할 인덱스</param>
    /// <param name="node">추가할 새 노드</param>
    void SinglyCircularLinkedList::Insert(size_t index, SinglyCircularLinkedListNode* node)
    {
    	if (index > m_count)
    	{
    		throw std::out_of_range("index");
    	}
    
    	if (node == nullptr || node->m_next != nullptr)
    	{
    		throw std::invalid_argument("node");
    	}
    
    	SinglyCircularLinkedListNode* prevNode{ nullptr };
    	SinglyCircularLinkedListNode* curNode{ m_head };
    	while (index--)
    	{
    		prevNode = curNode;
    		curNode = curNode->m_next;
    	}
    
    	node->m_next = curNode;
    
    	if (prevNode != nullptr)
    	{
    		prevNode->m_next = node;
    	}
    	else
    	{
    		UpdateHead(node);
    	}
    
    	m_count++;
    }

     

    데이터 삭제 메서드 구현

    데이터 삭제 연산에 필요한 메서드들을 구현한다.

     

    SinglyCircularLinkedList.cpp

    /// <summary>
    /// SinglyCircularLinkedList에서 가장 처음 일치한 지정된 값을 포함한 노드를 제거한다.
    /// </summary>
    /// <param name="value">제거할 값</param>
    bool SinglyCircularLinkedList::Remove(int value)
    {
    	if (m_head != nullptr)
    	{
    		SinglyCircularLinkedListNode* curNode{ m_head };
    		do
    		{
    			if (curNode->m_data == value)
    			{
    				Remove(curNode);
    				return true;
    			}
    			curNode = curNode->m_next;
    		} while (curNode != m_head);
    	}
    
    	return false;
    }
    
    /// <summary>
    /// SinglyCircularLinkedList에서 지정된 노드를 제거한다.
    /// </summary>
    /// <param name="node">제거할 노드</param>
    void SinglyCircularLinkedList::Remove(const SinglyCircularLinkedListNode* node)
    {
    	if (node == nullptr)
    	{
    		throw std::invalid_argument("node");
    	}
    
    	if (m_head != nullptr)
    	{
    		SinglyCircularLinkedListNode* prevNode{ nullptr };
    		SinglyCircularLinkedListNode* curNode{ m_head };
    		do
    		{
    			if (curNode == node)
    			{
    				if (prevNode != nullptr)
    				{
    					prevNode->m_next = curNode->m_next;
    				}
    				else
    				{
    					UpdateHead(curNode->m_next);
    				}
    				PushNode(curNode);
    				m_count--;
    				return;
    			}
    			prevNode = curNode;
    			curNode = curNode->m_next;
    		} while (curNode != m_head);
    	}
    
    	throw std::out_of_range("node");
    }
    
    /// <summary>
    /// SinglyCircularLinkedList의 모든 노드를 제거한다.
    /// </summary>
    void SinglyCircularLinkedList::Clear()
    {
    	if (m_head != nullptr)
    	{
    		SinglyCircularLinkedListNode* head{ m_head };
    		do
    		{
    			SinglyCircularLinkedListNode* curNode{ m_head };
    			m_head = m_head->m_next;
    			PushNode(curNode);
    		} while (m_head != head);
    		m_head = nullptr;
    	}
    	m_count = 0;
    }

     

    기능 메서드 구현

    자료구조를 효율적으로 사용하기 위한 기능 메서드를 구현한다.

     

    SinglyCircularLinkedList.cpp

    /// <summary>
    /// 지정한 값을 포함한 노드가 존재하는지 확인한다.
    /// </summary>
    /// <param name="value">찾을 값</param>
    /// <returns>값의 존재 여부</returns>
    bool SinglyCircularLinkedList::Contains(int value)
    {
    	if (m_head != nullptr)
    	{
    		SinglyCircularLinkedListNode* curNode{ m_head };
    		do
    		{
    			if (curNode->m_data == value)
    			{
    				return true;
    			}
    			curNode = curNode->m_next;
    		} while (curNode != m_head);
    	}
    	return false;
    }
    
    /// <summary>
    /// 지정한 노드가 SinglyCircularLinkedList에 포함되는지 확인한다.
    /// </summary>
    /// <param name="node">찾을 노드</param>
    /// <returns>노드의 포함 여부</returns>
    bool SinglyCircularLinkedList::Contains(const SinglyCircularLinkedListNode* node)
    {
    	if (m_head != nullptr)
    	{
    		SinglyCircularLinkedListNode* curNode{ m_head };
    		do
    		{
    			if (curNode == node)
    			{
    				return true;
    			}
    			curNode = curNode->m_next;
    		} while (curNode != m_head);
    	}
    	return false;
    }
    
    /// <summary>
    /// 지정한 값을 포함하는 가장 처음 일치하는 노드를 반환한다.
    /// </summary>
    /// <param name="value">찾을 값</param>
    /// <returns>지정한 값을 포함하는 노드(없는 경우: nullptr)</returns>
    SinglyCircularLinkedListNode* SinglyCircularLinkedList::Find(int value)
    {
    	if (m_head != nullptr)
    	{
    		SinglyCircularLinkedListNode* curNode{ m_head };
    		do
    		{
    			if (curNode->m_data == value)
    			{
    				return curNode;
    			}
    			curNode = curNode->m_next;
    		} while (curNode != m_head);
    	}
    	return nullptr;
    }
    
    /// <summary>
    /// 지정한 값을 포함하는 가장 마지막 일치하는 노드를 반환한다.
    /// </summary>
    /// <param name="value">찾을 값</param>
    /// <returns>지정한 값을 포함하는 노드(없는 경우: nullptr)</returns>
    SinglyCircularLinkedListNode* SinglyCircularLinkedList::FindLast(int value)
    {
    	SinglyCircularLinkedListNode* matchNode{ nullptr };
    
    	if (m_head != nullptr)
    	{
    		SinglyCircularLinkedListNode* curNode{ m_head };
    		do
    		{
    			if (curNode->m_data == value)
    			{
    				matchNode = curNode;
    			}
    			curNode = curNode->m_next;
    		} while (curNode != m_head);
    	}
    	return matchNode;
    }

     

      이중 원형 연결 리스트 구현 

    DoublyLinkedList를 변형하여 이중 원형 연결 리스트를 구현한다.

     

    DoublyCircularLinkedList.h

    #pragma once
    #include <xutility>
    #include <iostream>
    
    struct DoublyCircularLinkedListNode
    {
    	DoublyCircularLinkedListNode() {}
    	DoublyCircularLinkedListNode(int value) { m_data = value; }
    
    	int m_data{ 0 };
    	DoublyCircularLinkedListNode* m_prev{ nullptr };
    	DoublyCircularLinkedListNode* m_next{ nullptr };
    };
    
    class DoublyCircularLinkedList
    {
    public:
    #pragma region 생성자
    	DoublyCircularLinkedList();
    	DoublyCircularLinkedList(const DoublyCircularLinkedList& other);
    	~DoublyCircularLinkedList();
    #pragma endregion
    
    #pragma region 속성
    	const size_t Count() { return m_count; }
    	DoublyCircularLinkedListNode& First() { return *m_head; }
    	DoublyCircularLinkedListNode& Last() { return *m_tail; }
    #pragma endregion
    
    #pragma region 메서드
    	void AddFirst(int value);
    	void AddFirst(DoublyCircularLinkedListNode* node);
    	void AddLast(int value);
    	void AddLast(DoublyCircularLinkedListNode* node);
    	void Insert(size_t index, int value);
    	void Insert(size_t index, DoublyCircularLinkedListNode* node);
    
    	bool RemoveFirst(int value);
    	bool RemoveLast(int value);
    	void Remove(const DoublyCircularLinkedListNode* node);
    	void Clear();
    
    	bool Contains(int value);
    	bool Contains(const DoublyCircularLinkedListNode* node);
    	DoublyCircularLinkedListNode* Find(int value);
    	DoublyCircularLinkedListNode* FindLast(int value);
    #pragma endregion
    
    private:
    #pragma region Class Util
    	DoublyCircularLinkedListNode* PopNode(int value);
    	void PushNode(DoublyCircularLinkedListNode* node);
    #pragma endregion
    	
    private:
    #pragma region 변수
    	size_t m_count;
    	DoublyCircularLinkedListNode* m_head;
    	DoublyCircularLinkedListNode* m_tail;
    	DoublyCircularLinkedListNode* m_free;
    #pragma endregion
    };

     

    생성자, 소멸자 구현

    기본 생성자와 DoublyCircularLinkedList를 인자로 받는 복사 생성자를 구현한다.

     

    DoublyCircularLinkedList.cpp

    /// <summary>
    /// 비어있는 DoublyCircularLinkedList를 생성한다.
    /// </summary>
    DoublyCircularLinkedList::DoublyCircularLinkedList()
    	: m_count(0), m_head(nullptr), m_tail(nullptr), m_free(nullptr)
    {
    }
    
    /// <summary>
    /// 다른 DoublyCircularLinkedList가 가지고 있는 노드를 복사해 DoublyCircularLinkedList를 생성한다.
    /// </summary>
    /// <param name="other">기준이 될 DoublyCircularLinkedList</param>
    DoublyCircularLinkedList::DoublyCircularLinkedList(const DoublyCircularLinkedList& other)
    	: m_count(other.m_count), m_head(nullptr), m_tail(nullptr), m_free(nullptr)
    {
    	if (other.m_head == nullptr)
    	{
    		return;
    	}
    
    	DoublyCircularLinkedListNode* curNode{ other.m_head };
    
    	m_head = m_tail = PopNode(curNode->m_data);
    	curNode = curNode->m_next;
    
    	while (curNode->m_prev != other.m_tail)
    	{
    		DoublyCircularLinkedListNode* newNode{ PopNode(curNode->m_data) };
    		m_tail->m_next = newNode;
    		newNode->m_prev = m_tail;
    		m_tail = newNode;
    		curNode = curNode->m_next;
    	}
    
    	m_head->m_prev = m_tail;
    	m_tail->m_next = m_head;
    }
    
    /// <summary>
    /// 메모리 누수를 막기 위해 동적 생성한 노드들을 제거한다.
    /// </summary>
    DoublyCircularLinkedList::~DoublyCircularLinkedList()
    {
    	if (m_head != nullptr)
    	{
    		DoublyCircularLinkedListNode* head{ m_head };
    		do
    		{
    			DoublyCircularLinkedListNode* curNode{ m_head };
    			m_head = m_head->m_next;
    			delete curNode;
    		} while (m_head != head);
    	}
    
    	while (m_free != nullptr)
    	{
    		DoublyCircularLinkedListNode* curNode{ m_free };
    		m_free = m_free->m_next;
    		delete curNode;
    	}
    }

     

    데이터 삽입 메서드 구현

    데이터 삽입 연산에 필요한 메서드들을 구현한다.

     

    DoublyCircularLinkedList.cpp

    /// <summary>
    /// DoublyCircularLinkedList의 시작 위치에 지정한 값이 포함된 새 노드를 추가한다.
    /// </summary>
    /// <param name="value">추가할 값</param>
    void DoublyCircularLinkedList::AddFirst(int value)
    {
    	DoublyCircularLinkedListNode* newNode{ PopNode(value) };
    	AddFirst(newNode);
    }
    
    /// <summary>
    /// DoublyCircularLinkedList의 시작 위치에 지정한 노드를 추가한다.
    /// </summary>
    /// <param name="node">추가할 새 노드</param>
    void DoublyCircularLinkedList::AddFirst(DoublyCircularLinkedListNode* node)
    {
    	if (node == nullptr || node->m_prev != nullptr || node->m_next != nullptr)
    	{
    		throw std::invalid_argument("node");
    	}
    
    	node->m_next = m_head;
    	if (m_head != nullptr)
    	{
    		m_head->m_prev = node;
    		m_head = node;
    	}
    	else
    	{
    		m_head = m_tail = node;
    	}
    
    	m_head->m_prev = m_tail;
    	m_tail->m_next = m_head;
    
    	m_count++;
    }
    
    /// <summary>
    /// DoublyCircularLinkedList의 끝 위치에 지정한 값이 포함된 새 노드를 추가한다.
    /// </summary>
    /// <param name="value">추가할 값</param>
    void DoublyCircularLinkedList::AddLast(int value)
    {
    	DoublyCircularLinkedListNode* newNode{ PopNode(value) };
    	AddLast(newNode);
    }
    
    /// <summary>
    /// DoublyCircularLinkedList의 끝 위치에 지정한 노드를 추가한다.
    /// </summary>
    /// <param name="node">추가할 새 노드</param>
    void DoublyCircularLinkedList::AddLast(DoublyCircularLinkedListNode* node)
    {
    	if (node == nullptr || node->m_prev != nullptr || node->m_next != nullptr)
    	{
    		throw std::invalid_argument("node");
    	}
    
    	node->m_prev = m_tail;
    	if (m_tail != nullptr)
    	{
    		m_tail->m_next = node;
    		m_tail = node;
    	}
    	else
    	{
    		m_head = m_tail = node;
    	}
    
    	m_head->m_prev = m_tail;
    	m_tail->m_next = m_head;
    
    	m_count++;
    }
    
    /// <summary>
    /// DoublyCircularLinkedList의 지정한 인덱스에 해당하는 위치에 지정한 값이 포함된 새 노드를 추가한다.
    /// </summary>
    /// <param name="index">값을 추가할 인덱스</param>
    /// <param name="value">추가할 값</param>
    void DoublyCircularLinkedList::Insert(size_t index, int value)
    {
    	DoublyCircularLinkedListNode* newNode{ PopNode(value) };
    	Insert(index, newNode);
    }
    
    /// <summary>
    /// DoublyCircularLinkedList의 지정한 인덱스에 해당하는 위치에 지정된 노드를 추가한다.
    /// </summary>
    /// <param name="index">새 노드를 추가할 인덱스</param>
    /// <param name="node">추가할 새 노드</param>
    void DoublyCircularLinkedList::Insert(size_t index, DoublyCircularLinkedListNode* node)
    {
    	if (index > m_count)
    	{
    		throw std::out_of_range("index");
    	}
    
    	if (node == nullptr || node->m_next != nullptr)
    	{
    		throw std::invalid_argument("node");
    	}
    
    	DoublyCircularLinkedListNode* curNode{ m_head };
    	DoublyCircularLinkedListNode* prevNode{ m_tail };
    	for (int i = 0; i < index; i++)
    	{
    		prevNode = curNode;
    		curNode = curNode->m_next;
    	}
    
    	node->m_prev = prevNode;
    	if (prevNode != nullptr)
    	{
    		prevNode->m_next = node;
    	}
    	node->m_next = curNode;
    	if (curNode != nullptr)
    	{
    		curNode->m_prev = node;
    	}
    
    	if (index == 0)
    	{
    		m_head = node;
    	}
    	if (index == m_count)
    	{
    		m_tail = node;
    	}
    
    	m_count++;
    }

     

    데이터 삭제 메서드 구현

    데이터 삭제 연산에 필요한 메서드들을 구현한다.

     

    DoublyCircularLinkedList.cpp

    /// <summary>
    /// DoublyCircularLinkedList에서 가장 처음 일치한 지정된 값을 포함한 노드를 제거한다.
    /// </summary>
    /// <param name="value">제거할 값</param>
    bool DoublyCircularLinkedList::RemoveFirst(int value)
    {
    	bool foundNode{ false };
    	DoublyCircularLinkedListNode* curNode{ m_head };
    
    	if (m_head != nullptr)
    	{
    		do
    		{
    			if (curNode->m_data == value)
    			{
    				foundNode = true;
    				break;
    			}
    			curNode = curNode->m_next;
    		} while (curNode != m_head);
    	}
    
    	if (!foundNode)
    	{
    		return false;
    	}
    
    	Remove(curNode);
    
    	return true;
    }
    
    /// <summary>
    /// DoublyCircularLinkedList에서 가장 처음 일치한 지정된 값을 포함한 노드를 제거한다.
    /// </summary>
    /// <param name="value">제거할 값</param>
    bool DoublyCircularLinkedList::RemoveLast(int value)
    {
    	bool foundNode{ false };
    	DoublyCircularLinkedListNode* curNode{ m_tail };
    
    	if (m_tail != nullptr)
    	{
    		do
    		{
    			if (curNode->m_data == value)
    			{
    				foundNode = true;
    				break;
    			}
    			curNode = curNode->m_prev;
    		} while (curNode != m_tail);
    	}
    
    	if (!foundNode)
    	{
    		return false;
    	}
    
    	Remove(curNode);
    
    	return true;
    }
    
    /// <summary>
    /// DoublyCircularLinkedList에서 지정된 노드를 제거한다.
    /// </summary>
    /// <param name="node">제거할 노드</param>
    void DoublyCircularLinkedList::Remove(const DoublyCircularLinkedListNode* node)
    {
    	if (node == nullptr)
    	{
    		throw std::invalid_argument("node");
    	}
    
    	bool foundNode{ false };
    	DoublyCircularLinkedListNode* curNode{ m_head };
    	
    	if (m_head != nullptr)
    	{
    		do
    		{
    			if (curNode == node)
    			{
    				foundNode = true;
    				break;
    			}
    			curNode = curNode->m_next;
    		} while (curNode != m_head);
    	}
    
    	if (!foundNode)
    	{
    		throw std::out_of_range("node");
    	}
    
    	DoublyCircularLinkedListNode* prevNode{ curNode->m_prev };
    	DoublyCircularLinkedListNode* nextNode{ curNode->m_next };
    	prevNode->m_next = nextNode;
    	if (prevNode == m_tail)
    	{
    		m_head = nextNode;
    	}
    
    	nextNode->m_prev = prevNode;
    	if (nextNode == m_head)
    	{
    		m_tail = prevNode;
    	}
    
    	if (m_head == m_tail && m_tail == curNode)
    	{
    		m_head = m_tail = nullptr;
    	}
    
    	PushNode(curNode);
    
    	m_count--;
    }
    
    /// <summary>
    /// DoublyCircularLinkedList의 모든 노드를 제거한다.
    /// </summary>
    void DoublyCircularLinkedList::Clear()
    {
    	if (m_head != nullptr)
    	{
    		DoublyCircularLinkedListNode* head{ m_head };
    		do
    		{
    			DoublyCircularLinkedListNode* curNode{ m_head };
    			m_head = m_head->m_next;
    			PushNode(curNode);
    		} while (m_head != head);
    	}
    	m_head = m_tail = nullptr;
    	m_count = 0;
    }

     

    기능 메서드 구현

    자료구조를 효율적으로 사용하기 위한 기능 메서드를 구현한다.

     

    DoublyCircularLinkedList.cpp

    /// <summary>
    /// 지정한 값을 포함한 노드가 존재하는지 확인한다.
    /// </summary>
    /// <param name="value">찾을 값</param>
    /// <returns>값의 존재 여부</returns>
    bool DoublyCircularLinkedList::Contains(int value)
    {
    	if (m_head != nullptr)
    	{
    		DoublyCircularLinkedListNode* curNode{ m_head };
    		do
    		{
    			if (curNode->m_data == value)
    			{
    				return true;
    			}
    			curNode = curNode->m_next;
    		} while (curNode != m_head);
    	}
    	return false;
    }
    
    /// <summary>
    /// 지정한 노드가 DoublyCircularLinkedList에 포함되는지 확인한다.
    /// </summary>
    /// <param name="node">찾을 노드</param>
    /// <returns>노드의 포함 여부</returns>
    bool DoublyCircularLinkedList::Contains(const DoublyCircularLinkedListNode* node)
    {
    	if (m_head != nullptr)
    	{
    		DoublyCircularLinkedListNode* curNode{ m_head };
    		do
    		{
    			if (curNode == node)
    			{
    				return true;
    			}
    			curNode = curNode->m_next;
    		} while (curNode != m_head);
    	}
    	return false;
    }
    
    /// <summary>
    /// 지정한 값을 포함하는 가장 처음 일치하는 노드를 반환한다.
    /// </summary>
    /// <param name="value">찾을 값</param>
    /// <returns>지정한 값을 포함하는 노드(없는 경우: nullptr)</returns>
    DoublyCircularLinkedListNode* DoublyCircularLinkedList::Find(int value)
    {
    	if (m_head != nullptr)
    	{
    		DoublyCircularLinkedListNode* curNode{ m_head };
    		do
    		{
    			if (curNode->m_data == value)
    			{
    				return curNode;
    			}
    			curNode = curNode->m_next;
    		} while (curNode != m_head);
    	}
    	return nullptr;
    }
    
    /// <summary>
    /// 지정한 값을 포함하는 가장 마지막 일치하는 노드를 반환한다.
    /// </summary>
    /// <param name="value">찾을 값</param>
    /// <returns>지정한 값을 포함하는 노드(없는 경우: nullptr)</returns>
    DoublyCircularLinkedListNode* DoublyCircularLinkedList::FindLast(int value)
    {
    	if (m_tail != nullptr)
    	{
    		DoublyCircularLinkedListNode* curNode{ m_tail };
    		do
    		{
    			if (curNode->m_data == value)
    			{
    				return curNode;
    			}
    			curNode = curNode->m_prev;
    		} while (curNode != m_tail);
    	}
    	return nullptr;
    }

    댓글

Designed by Tistory.