๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
์•Œ๊ณ ๋ฆฌ์ฆ˜/์ž๋ฃŒ๊ตฌ์กฐ

5. ์›ํ˜• ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ (Circular Linked List)

by ๐Ÿณ Laboon 2024. 2. 10.
์›ํ˜• ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋ž€?

 

๋‹จ์ˆœ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์—์„œ ๋์ด ์ฒ˜์Œ๊ณผ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š” ํ˜•ํƒœ๋ฅผ ์›ํ˜• ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

 

STL์—๋„ ๊ตฌํ˜„๋˜์–ด์žˆ์ง€ ์•Š๊ณ  ์•„์ง ํ•™์ƒ ์ˆ˜์ค€์ด์ง€๋งŒ, ์‹ค์ œ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ฒฝ์šฐ๋„ ๋ณธ ์ ์ด ๋งŽ์ด ์—†์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ๋‹จ์ˆœํ•˜๊ฒŒ๋งŒ ๋งŒ๋“ค์–ด๋ณด๋„๋ก ํ•  ๊ฒƒ์ธ๋ฐ, ์ด์ค‘ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ ํ˜•ํƒœ๋กœ ๋งŒ๋“ค๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

(์‹ค์ œ๋กœ ์ˆœํ™˜์ ์ธ ์š”์†Œ๋Š” ํ ๋˜๋Š” ์žฌ๊ท€๋ฅผ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š”๋“ฏ)


์›ํ˜• ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(Circular Linked List) ๊ตฌํ˜„ํ•˜๊ธฐ 

 

๋งŽ์€ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜์ง€๋Š” ์•Š๊ฒ ์Šต๋‹ˆ๋‹ค.

๋…ธ๋“œ
#pragma once

template <typename T>
class Node {
public:
    Node(T data);
    
    T getData() const;
    Node* getNext() const;
    Node* getPrev() const;

    void setNext(Node* node);
    void setPrev(Node* node);

private:
    T data;
    Node* next;
    Node* prev;
};

template <typename T>
Node<T>::Node(T data) : data(data), next(nullptr), prev(nullptr) {}

template <typename T>
T Node<T>::getData() const {
    return data;
}

template <typename T>
Node<T>* Node<T>::getNext() const {
    return next;
}

template <typename T>
Node<T>* Node<T>::getPrev() const {
    return prev;
}

template <typename T>
void Node<T>::setNext(Node* node) {
    next = node;
}

template <typename T>
void Node<T>::setPrev(Node* node) {
    prev = node;
}

 

์›ํ˜• ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์˜ ๋…ธ๋“œ๋Š” ๋‹จ์ˆœ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ ๊ตฌ์กฐ์ผ ๊ฒฝ์šฐ ๋‹จ์ˆœ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ ํฌ์ŠคํŠธ์—์„œ ์‚ฌ์šฉ๋œ ๋…ธ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

ํ˜„์žฌ๋Š” ์ด์ค‘ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ ๊ตฌ์กฐ์—์„œ ์›ํ˜• ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋ฅผ ๊ฐœ๋ฐœํ•˜๊ธฐ๋กœ ์„ค๊ณ„ํ–ˆ์Šต๋‹ˆ๋‹ค.

 

์›ํ˜• ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ ํด๋ž˜์Šค
#pragma once
#include "CircularLinkedListNode.h"
#include <iostream>

// Prototype
template <typename T>
class CircularLinkedList {
public:
    CircularLinkedList();

    void push_front(const T& value);
    void push_back(const T& value);
    void pop_front();
    void pop_back();
    void travel();

private:
    Node<T>* head;
    Node<T>* tail;
};

template <typename T>
CircularLinkedList<T>::CircularLinkedList() : head(nullptr), tail(nullptr) {}

template <typename T>
void CircularLinkedList<T>::push_front(const T& value) {
	Node<T>* newNode = new Node<T>(value);
	if (head == nullptr) {
		head = newNode;
		tail = newNode;
		head -> setNext(newNode);
		head -> setPrev(newNode);
		tail -> setNext(newNode);
		tail -> setPrev(newNode);
	} else {
		head -> setPrev(newNode);
		tail -> setNext(newNode);
		newNode -> setNext(head);
		newNode -> setPrev(tail);
		head = newNode;
	}
}

template <typename T>
void CircularLinkedList<T>::push_back(const T& value) {
	if (head == nullptr) {
		push_front(value);
	} else {
		Node<T>* newNode = new Node<T>(value);
		head -> setPrev(newNode);
		tail -> setNext(newNode);
		newNode -> setNext(head);
		newNode -> setPrev(tail);
		tail = newNode;
	}
}

template <typename T>
void CircularLinkedList<T>::pop_front() {
	if(head == tail) {
		delete head;
		delete tail;
		head == nullptr;
		tail == nullptr;
	} else {
		Node<T>* newHead = head -> getNext();
		tail -> setNext(newHead);
		newHead -> setPrev(newHead);
		delete head; 
		head = newHead;
	}
}

template <typename T>
void CircularLinkedList<T>::pop_back() {
	if(head == tail) {
		delete head;
		delete tail;
		head == nullptr;
		tail == nullptr;
	} else {
		Node<T>* newTail = tail -> getPrev();
		newTail -> setNext(head);
		head -> setPrev(newTail);
		delete tail; 
		tail = newTail;
	}
}

template <typename T>
void CircularLinkedList<T>::travel() {
	Node<T>* temp = head;
	do {
		std::cout << (temp -> getData()) << ' ';
		temp = temp -> getNext();
	}
	while (temp != head);
	std::cout << '\n';
}

 

์ด์ค‘ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์—์„œ iterator๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ๊ฐ„๋‹จํ•˜๊ฒŒ๋งŒ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

๋งจ ์•ž ๋’ค์— ์ถ”๊ฐ€/์‚ญ์ œ ํ•˜๋Š” ์—ฐ์‚ฐ๊ณผ ๋ชจ๋“  ์›์†Œ๋ฅผ ํƒ์ƒ‰ํ•˜๋Š” ๊ณผ์ •๋งŒ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

 

โ€ป ์ถ”๊ฐ€ ์—ฐ์‚ฐ ์‹œ ์ฃผ์˜ํ•ด์•ผ ํ•  ์ .

๋งŒ์•ฝ, ์ฒ˜์Œ์œผ๋กœ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒฝ์šฐ ๋ฆฌ์ŠคํŠธ๋Š” ๋น„์–ด์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๋•Œ, ์›ํ˜• ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ์—์„œ ์ฒซ ์›์†Œ๋Š” ๋ณธ์ธ ์Šค์Šค๋กœ๋ฅผ ๊ฐ€๋ฅดํ‚ค๊ฒŒ ๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค.

์›์†Œ๊ฐ€ ๋’ค์— ์ถ”๊ฐ€ ๋˜๋Š” ๊ฒฝ์šฐ, ์ƒˆ๋กœ ์ถ”๊ฐ€๋˜๋Š” ์›์†Œ๋ฅผ Now(ํ˜„์žฌ ์›์†Œ)๋ผ๊ณ  ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

1. Tail(๋งˆ์ง€๋ง‰ ์›์†Œ)์˜ ๋‹ค์Œ ๊ฐ’์œผ๋กœ Now๊ฐ€ ์™€์•ผํ•˜๊ณ  Head(์ฒซ ์›์†Œ)์˜ ์ด์ „ ๊ฐ’์œผ๋กœ Now๊ฐ€ ์™€์•ผํ•ฉ๋‹ˆ๋‹ค.

2. Now์˜ ๋‹ค์Œ ์›์†Œ๋Š” Tail์ด ๋˜์–ด์•ผํ•˜๊ณ  Now์˜ ์ด์ „ ์›์†Œ๋Š” Head๊ฐ€ ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

์›์†Œ๊ฐ€ ์•ž์— ์ถ”๊ฐ€ ๋˜๋Š” ๊ฒฝ์šฐ๋Š” ๋ฐ˜๋Œ€ ์ผ€์ด์Šค๋ผ์„œ ์„ค๋ช…ํ•˜์ง€ ์•Š๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์›์†Œ๊ฐ€ ์‚ญ์ œ๋˜๋Š” ๊ฒฝ์šฐ๋Š”, ์›์†Œ๊ฐ€ ํ•˜๋‚˜๋งŒ ์žˆ์„ ๊ฒฝ์šฐ head์™€ tail์ด ๊ฐ™์€ ๊ฒฝ์šฐ (์ฃผ์†Œ ๊ฐ’์„ ๊ธฐ์ค€์œผ๋กœ ๋น„๊ตํ•  ์ˆ˜ ์žˆ์Œ)

1. ์ด ๋•Œ, head์™€ tail์— ํ• ๋‹น๋œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‚ญ์ œํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๊ณ  ๋ชจ๋‘ null๊ฐ’์œผ๋กœ ๋ฐ”๊พธ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋งจ ๋’ค ๋ฐ์ดํ„ฐ๊ฐ€ ์‚ญ์ œ๊ฐ€ ๋˜๋Š” ๊ฒฝ์šฐ

1. Prev(Tail์˜ ์ด์ „ ๊ฐ’)๊ฐ€ Tail์ด ๋˜์–ด์•ผํ•ฉ๋‹ˆ๋‹ค.

2. Prev์˜ ๋‹ค์Œ ๊ฐ’์„ Next(Tail์˜ ๋‹ค์Œ ๊ฐ’)์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

3. Next์˜ ์ด์ „ ๊ฐ’์„ Prev๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

4. ๊ธฐ์กด์˜ Tail์— ํ• ๋‹น๋œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ•ด์ œํ•ด์ฃผ๊ณ  Prev๋ฅผ Tail๋กœ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

 

์•ž์˜ ์›์†Œ๊ฐ€ ์‚ญ์ œ๋˜๋Š” ๊ฒฝ์šฐ๋„ ๋ฐ˜๋Œ€ ์ผ€์ด์Šค๋ผ์„œ ์„ค๋ช…ํ•˜์ง€ ์•Š๊ฒ ์Šต๋‹ˆ๋‹ค.

 

๋งˆ์ง€๋ง‰์œผ๋กœ ํƒ์ƒ‰ํ•˜๋Š” ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค.

(head == tail) != null ์ด๋ฏ€๋กœ do์—์„œ ๋จผ์ € ์ถœ๋ ฅํ•œ ๋’ค while๋ฌธ์—์„œ ์กฐ๊ฑด ๊ฒ€์‚ฌ๋ฅผ ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

 

์‹คํ–‰
#include <iostream>
#include "CircularLinkedList.h"

using namespace std;

int main() {
	CircularLinkedList<int> customList;
	
	cout << "===== push_back & travel =====\n";
	for (int i = 10; i <= 50; i += 10) {
		customList.push_back(i);
	}
	customList.travel();
	
	cout << "\n===== push_front & travel =====\n";
	for (int i = 1; i <= 5; i++) {
		customList.push_front(i);
	}
	customList.travel();
	
	cout << "\npop_front & pop_back & travel \n";
	customList.pop_front();
	customList.pop_back();
	customList.travel();
	
	return 0;
}

 

๊ฒฐ๊ณผ

 

GitHub ๋งํฌ URL

https://github.com/jihwankim128/datastructure

 

GitHub - jihwankim128/datastructure

Contribute to jihwankim128/datastructure development by creating an account on GitHub.

github.com