# Learning notes - circular linked list (expressed in C + +)

Students in school, please criticize and correct the deficiencies or errors in the narration.

We have learned the one-way linked list before, because the continuity does not need to be guaranteed during storage. Each node stores direct successors. We can easily insert and delete and expand the space. But we also found a disadvantage, that is, every time we operate on the list, we need to traverse from beginning to end or reach a node in the linked list, that is, the unity of direction.
At this time, we propose a method: set the tail node in the single linked list to node_ The next node attribute nextnode of end points to the head of the head node table. In this way, the linked list can form a loop, and the traversal can be completed no matter where it starts.

## Node template definition of circular linked list

The node definition of circular linked list is the same as that of unidirectional linked list. We can find that the only difference between circular linked list and unidirectional linked list is the processing of tail nodes.

```template <class T>
class Node {
protected:
T data;
Node<T>* nextnode;
public:
Node();//Used to create an empty node
Node(const T& obj);//Create data only nodes
Node(const T& obj, Node<T>* address);//Create known nodes
Node(const Node<T>& node);//Replication node

virtual Node<T>* getNextNode();//Return next node address
virtual void setNextNode(Node<T>* const address);//Set next node
virtual T& showData();//Return data

~Node();//Destroy node
};
```

## Definition of circular linked list template

In the circular linked list, we directly introduce the same definition as the one-way linked list. Because the circular linked list is a deformation of the one-way linked list.

```template<class T> class CircularList {
protected:

public:
CircularList(); 	//Constructor to construct an empty table

public:
virtual void insert(const T& obj, int index); 	//Insert an element into the table
virtual T& check(int index)const; 	//View an element
virtual bool remove(int index); 	//Delete an element
virtual int length()const; 	//Return table length

public:
};
```

## Implementation of circular linked list

#### Implementation of constructor

The constructor is similar to the one-way linked list. In the specific implementation, you need to instantiate a head node, and then set the next node of the head node to point to the head to realize the empty table definition of a circular linked list. What is a head node and why a head node should be used? For details, please refer to the notes of the one-way linked list (hyperlink: Single linked list).

```template<class T>
CircularList<T>::CircularList() {
LENGTH = 0;  	//Set the table length to 0
}
```

We should note that because the next node at the end of the list points to the head, the way we judge whether to reach the end of the linked list will change.

```template<class T>
Node<T>* temp = new Node<T>(dt, head); 	//Create a new node. The new node is connected to the end of the linked list, so the next node points to the head
if(temp == nullptr) { return; } 	//Failed to create node, return
node = node->getNextNode();
}
node->setNextNode(temp); 	//Connect the new node into the circular linked list
LENGTH++;
return;
}
```

#### Find elements in a linked list

We also start from the beginning and traverse from the beginning to the end of the linked list.

```template<class T>
T& CircularList<T>::check(int index) {
index--; 	//Incoming is a natural sort, convert it to start from 0
if(index < 0 || index >= LENGTH) { throw "ERROR OBJ"; }
Node<T>* node = head->getNextNode(); 	//Get next node
for(int i = 1; i <= index; i++) {
node = node->getNextNode();
}
return node->showData();
}
```

#### Insert an element into the linked list

Insert element is the same as one-way linked list. Find the insertion point and insert. We know that if we know the back of the p node in the inserted linked list and know the address of p, we only need to execute:

```insert_element->setNextNode(p->getNextNode());
p->setNextNode(insert_element);
```

At this time, the time complexity of insert() method is of constant order.
When we only know the subscript to be inserted or the data sample of the insertion position, we need to traverse the elements of the array. At this time, the time complexity of the insert() method is linear.

```template<class T>
void CircularList<T>::insert(int index, const T& dt) {
for(int i = 1; i < index; i++) {
node = node->getNextNode();
}
Node<T>* temp = new Node<T>(dt, node->getNextNode()); 	//Create a new node
if(temp == nullptr) { return; }
node->setNextNode(temp);
return;
}
```

#### Delete an element from the linked list

Similar to the one-way linked list, traverse the linked list from the beginning, compare the examples or reach the given subscript, and delete the corresponding elements.

```template<class T>
bool CircularList<T>::remove(int index) {
index--;
if(index <0 || index >= LENGTH) {
return false;
}