일반 단일 연결 리스트와는 달리 원형 단일 연결 리스트의 마지막 노드는 첫 번째 노드를 가리키며 리스트 순회가 시작 노드로 돌아가면서 계속됩니다.
각 노드는 다음 노드와 연결 되며, 마지막 노드느느 첫 번째 노드로 되돌아가는 루프를 형성합니다. 이러한 구조는 전체 리스트를 효율적으로 순회할 수 있게 합니다. 일반 단일 연결 리스트와 구별되는 중요한 특징은 끝에 nullptr 개념이 없어진다는 것입니다.
#include <iostream>
using namespace std;
template <typename T>
struct Node{
T data;
struct Node* next;
};
template <typename T>
class CircularSinglyLinkedList{
private:
Node<T>* head_;
public:
CircularSinglyLinkedList();
~CircularSinglyLinkedList();
void printAll();
Node<T>* createNode(T newData);
void destroyNode(Node<T>* node);
void appendNode(Node<T>* newNode);
void insertNode(Node<T>* current, Node<T>* newNode);
void insertNewHead(Node<T>* newHead);
void removeNode(Node<T>* Remove);
void removeHead();
void removeTail();
int getSize();
Node<T>* getNodeAt(int location);
};
template <typename T>
CircularSinglyLinkedList<T>::CircularSinglyLinkedList():head_(nullptr){
}
template <typename T>
CircularSinglyLinkedList<T>::~CircularSinglyLinkedList(){
Node<T>* current = head_;
while (current != nullptr){
Node<T>* temp = current;
current = current->next;
destroyNode(temp);
}
}
template <typename T>
void CircularSinglyLinkedList<T>::printAll(){
Node<T>* current = head_;
cout << "start -> ";
while (current->next != head_){
cout << current->data << " -> ";
current = current->next;
}
cout << current->data;
cout << " -> end\n";
}
template <typename T>
Node<T>* CircularSinglyLinkedList<T>::createNode(T newData){
Node<T>* newNode = new Node<T>;
newNode->data = newData;
newNode->next = nullptr;
return newNode;
}
template <typename T>
void CircularSinglyLinkedList<T>::destroyNode(Node<T>* node){
node->next = nullptr;
delete node;
}
template <typename T>
void CircularSinglyLinkedList<T>::appendNode(Node<T>* newNode){
if (head_ == nullptr){
head_ = newNode;
head_->next = head_;
}
else {
Node<T>* current = head_;
while (current->next != head_){
current = current->next;
}
newNode->next = current->next;
current->next = newNode;
}
}
template <typename T>
void CircularSinglyLinkedList<T>::insertNode(Node<T>* current, Node<T>* newNode){
newNode->next = current->next;
current->next = newNode;
}
template <typename T>
void CircularSinglyLinkedList<T>::insertNewHead(Node<T>* newHead){
Node<T>* current = head_;
while (current->next != head_){
current = current->next;
}
newHead->next = head_;
head_ = newHead;
current->next = head_;
}
template <typename T>
void CircularSinglyLinkedList<T>::removeNode(Node<T>* Remove){
if (Remove == head_){
removeHead();
}
else {
Node<T>* current = head_;
while (current->next != Remove){
current = current->next;
}
current->next = Remove->next;
Remove->next = nullptr;
}
}
template <typename T>
void CircularSinglyLinkedList<T>::removeHead(){
if (head_->next == head_){
head_ = nullptr;
}
else {//이거 수정해야 함.
Node<T>* current = head_;
while (current->next != head_){
current = current->next;
}
current->next = head_->next;
current = head_;
head_ = head_->next;
current->next = nullptr;
}
}
template <typename T>
void CircularSinglyLinkedList<T>::removeTail(){
Node<T>* tail = head_;
while (tail->next != head_){
tail = tail->next;
}
Node<T>* current = tail;
while (current->next != tail){
current = current->next;
}
current->next = head_;
tail->next = nullptr;
}
template <typename T>
int CircularSinglyLinkedList<T>::getSize(){
int count = 1;
Node<T>* current = head_;
current = current->next;
while (current != head_){
current = current->next;
count++;
}
return count;
}
template <typename T>
Node<T>* CircularSinglyLinkedList<T>::getNodeAt(int location){
Node<T>* current = head_;
while ((--location) > 0){
current = current->next;
}
return current;
}
int main(){
CircularSinglyLinkedList<int>* list = new CircularSinglyLinkedList<int>();
Node<int>* temp;
for (int i=0;i<3;i++){
temp = list->createNode(i+1);
list->appendNode(temp);
}
list->printAll();
for (int i=0;i<3;i++){
temp = list->createNode(i+4);
list->insertNewHead(temp);
}
list->printAll();
cout << "현재 노드의 개수 : " << list->getSize() << endl;
cout << "세 번째 노드 : " << list->getNodeAt(3)->data << endl;
list->removeHead();
list->printAll();
list->removeTail();
list->printAll();
}
출력
start -> 1 -> 2 -> 3 -> end
start -> 6 -> 5 -> 4 -> 1 -> 2 -> 3 -> end
현재 노드의 개수 : 6
세 번째 노드 : 4
start -> 5 -> 4 -> 1 -> 2 -> 3 -> end
start -> 5 -> 4 -> 1 -> 2 -> end