定义
- 头节点
和单链表一样, 只是最后一个节点的指针指向了头节点而不是nullptr
template <class T>
class Node {
public:
T val;
Node* next;
Node() = default;
Node(const T& t, Node* nxt = nullptr) : val(t), next(nxt) {}
};
定义及实现
template <typename T>
class CircularLinkedList {
private:
Node<T>* head;
size_t size;
public:
CircularLinkedList() : size{ 0 }, head{ nullptr } {}
~CircularLinkedList() {
while (head != nullptr) {
Node<T> p = head;
head = head->next;
delete p;
}
}
void insert(const T& t) {
Node<T>* node = new Node<T>(t);
if (head == nullptr) {
head = node;
head->next = head;
}
else {
node->next = head->next;
head->next = node;
}
++size;
}
bool remove(const T& t) {
if (size == 0)
throw "Exception : Remove form an empty List :(";
Node<T>* p = head;
Node<T>* i = head->next;
for (; i->val != t && i != head; i = i->next) {
p = i;
}
if (i == nullptr) {
return false;
}
--size;
if (size == 0) {
delete head;
head = nullptr;
}
else {
Node<T>* node = p->next;
p->next = node->next;
head = p;
delete node;
}
return true;
}
bool empty() { return size == 0 ? true : false; }
unsigned length() const { return size; }
Node<T>* getHead() const { return head; }
void merge(CircularLinkedList<T>& l) {
this->size += l.length();
Node<T>*lhead = l.getHead(), *ltail = lhead, *tail = head;
for (; ltail->next != lhead; ltail = ltail->next)
;
for (; tail->next != head; tail = tail->next)
;
tail->next = l.getHead();
ltail->next = head;
}
friend std::ostream& operator<<(std::ostream& os, const CircularLinkedList& l) {
if (l.head != nullptr) {
for (Node<T>* i = l.head->next; i != l.head; i = i->next) {
os << i->val << " ";
}
os << l.head->val;
}
else
os << "null ";
return os;
}
};
测试
int main(int argc, char const* argv[]) {
CircularLinkedList<string>* cl = new CircularLinkedList<string>();
cl->insert("sda");
cl->insert("sda1");
cl->insert("sd2");
cl->insert("sda3");
cl->insert("sda4");
cl->remove("sda");
cout << *cl << "\n";
CircularLinkedList<string>* cl1 = new CircularLinkedList<string>();
cl1->insert("sda");
cl1->insert("sda1");
cl1->insert("sd2");
cl1->insert("sda3");
cl1->insert("sda4");
cl1->remove("sda");
cout << *cl1 << "\n";
cl->merge(*cl1);
cout << *cl << "\n";
return 0;
}