在某些情况下可能会用到循环链表,其中的节点组成一个环:链表的长度是有限的,每个节点都有后继节点。
在循环单向链表的实现中,即使对链表的操作需要访问尾部节点及其头部节点,也可以只固定一个固定指针 tail。
用 C++ 进行对单指针的循环链表进行构建为:
// linked_lists.h
#ifndef LINKED_LIST_H
#define LINKED_LIST_H
using std::ostream;
using std::cout;
using std::endl;
class Circular_linked_list_node
{
public:
int info;
Circular_linked_list_node *next;
public:
Circular_linked_list_node()
{
info = 0;
next = nullptr;
}
Circular_linked_list_node(int i = 0, Circular_linked_list_node *p = nullptr)
{
info = i;
next = p;
}
~Circular_linked_list_node() {};
};
class Circular_linked_list
{
public:
Circular_linked_list_node *tail;
public:
Circular_linked_list()
{
tail = nullptr;
}
bool isempty()
{
return tail == nullptr;
}
bool inlist(int) const; // 表明不能修改 this 指针指向的对象
void addtohead(int);
void addtotail(int);
int deletefromhead();
int deletefromtail();
void deleteselect(int);
friend ostream & operator<<(ostream &, const Circular_linked_list &);
~Circular_linked_list();
};
#endif // !LINKED_LIST_H
// linked_lists.cpp
#include <iostream>
#include "linked_lists.h"
bool Circular_linked_list::inlist(int i) const
{
Circular_linked_list_node *tmp;
for (tmp = tail->next; tmp != tail && !(tmp->info == i); tmp = tmp->next);
if (tmp == tail)
return i == tail->info;
else
return true;
}
void Circular_linked_list::addtohead(int i)
{
if (isempty())
tail = new Circular_linked_list_node(i, nullptr), tail->next = tail;
else
tail->next = new Circular_linked_list_node(i, tail->next);
}
void Circular_linked_list::addtotail(int i)
{
if (isempty())
tail = new Circular_linked_list_node(i, nullptr), tail->next = tail;
else
tail->next = new Circular_linked_list_node(i, tail->next), tail = tail->next;
}
int Circular_linked_list::deletefromhead()
{
if (isempty())
return 0;
else
{
int i = tail->next->info;
tail->next = tail->next->next;
return i;
}
}
int Circular_linked_list::deletefromtail()
{
if (isempty())
return 0;
else
{
int i = tail->next->info;
Circular_linked_list_node *tmp;
for (tmp = tail->next; tmp->next != tail; tmp = tmp->next);
tmp->next = tail->next;
tail = tmp;
return i;
}
}
void Circular_linked_list::deleteselect(int i)
{
if (!isempty())
{
Circular_linked_list_node *tmp,*prev;
for (prev = tail,tmp = tail->next; tmp != tail && !(tmp->info == i); prev = prev->next,tmp = tmp->next);
if (tmp->info == i)
prev->next = tmp->next;
}
}
ostream & operator<<(ostream & out, const Circular_linked_list & p)
{
Circular_linked_list_node *tmp;
for (tmp = p.tail->next; tmp != nullptr && tmp != p.tail; tmp = tmp->next)
out << tmp->info << " ";
return out << p.tail->info;
}
Circular_linked_list::~Circular_linked_list()
{
for (Circular_linked_list_node *p; !isempty();)
{
p = tail->next;
delete tail;
tail = p;
}
}
// create_list.cpp
#include <iostream>
#include "linked_lists.h"
int main()
{
using namespace std;
//*********此处是循环链表——单指针测试代码********
Circular_linked_list list3;
cout << list3.isempty() << endl;
list3.addtohead(1);
list3.addtohead(2);
list3.addtohead(3);
list3.addtohead(4);
list3.addtotail(5);
list3.addtotail(6);
list3.addtotail(7);
list3.addtotail(8);
list3.deletefromhead();
list3.deletefromhead();
list3.deletefromtail();
list3.deletefromtail();
list3.deleteselect(5);
list3.deleteselect(12);
cout << list3.inlist(1) << endl;
cout << list3.inlist(10) << endl;
cout << list3.isempty() << endl;
cout << list3 << endl;
//***********************************/
system("pause");
return 0;
}
同样的如果要删除最后一个元素,也需要通过循环进行遍历,对于这样的问题,可以设置两个指针 head 和 tail。
用 C++ 进行对双指针的循环链表进行构建为:
// linked_lists.h
#ifndef LINKED_LIST_H
#define LINKED_LIST_H
using std::ostream;
using std::cout;
using std::endl;
class Circular_linked_list_tnodes
{
public:
int info;
Circular_linked_list_tnodes *prev, *next;
public:
Circular_linked_list_tnodes()
{
info = 0;
prev = next = nullptr;
}
Circular_linked_list_tnodes(int i = 0, Circular_linked_list_tnodes *p = nullptr, Circular_linked_list_tnodes *q = nullptr)
{
info = i;
prev = p;
next = q;
}
~Circular_linked_list_tnodes() {};
};
class Circular_tnodes_linked_list
{
public:
Circular_linked_list_tnodes *head, *tail;
public:
Circular_tnodes_linked_list()
{
head = tail = nullptr;
}
bool isempty()
{
return tail == nullptr;
}
bool inlist(int) const; // 表明不能修改 this 指针指向的对象
void addtohead(int);
void addtotail(int);
int deletefromhead();
int deletefromtail();
void deleteselect(int);
friend ostream & operator<<(ostream &, const Circular_tnodes_linked_list &);
~Circular_tnodes_linked_list();
};
#endif // !LINKED_LIST_H
// linked_lists.cpp
#include <iostream>
#include "linked_lists.h"
bool Circular_tnodes_linked_list::inlist(int i) const
{
Circular_linked_list_tnodes *tmp;
for (tmp = head; tmp != tail && !(tmp->info == i); tmp = tmp->next);
if (tmp == tail)
return i == tail->info;
else
return true;
}
void Circular_tnodes_linked_list::addtohead(int i)
{
if (isempty())
{
head = tail = new Circular_linked_list_tnodes(i, nullptr, nullptr);
tail->next = head->prev = tail, tail->prev = head->next = head;
}
else
{
head = new Circular_linked_list_tnodes(i, tail, head);
head->next->prev = head, head->prev->next = head;
}
}
void Circular_tnodes_linked_list::addtotail(int i)
{
if (isempty())
{
head = tail = new Circular_linked_list_tnodes(i, nullptr, nullptr);
tail->next = head->prev = tail, tail->prev = head->next = head;
}
else
{
tail = new Circular_linked_list_tnodes(i, tail, head);
tail->next->prev = tail, tail->prev->next = tail;
}
}
int Circular_tnodes_linked_list::deletefromhead()
{
if (isempty())
return 0;
else
{
int i = head->info;
Circular_linked_list_tnodes *tmp = head;
head = head->next;
head->prev = tail, tail->next = head, delete tmp;
return i;
}
}
int Circular_tnodes_linked_list::deletefromtail()
{
if (isempty())
return 0;
else
{
int i = head->info;
Circular_linked_list_tnodes *tmp = tail;
tail = tail->prev;
head->prev = tail, tail->next = head, delete tmp;
return i;
}
}
void Circular_tnodes_linked_list::deleteselect(int i)
{
if (!isempty())
{
Circular_linked_list_tnodes *tmp;
for (tmp = head; tmp != tail && !(tmp->info == i); tmp = tmp->next);
if (tmp->info == i)
tmp->prev->next = tmp->next, tmp->next->prev = tmp->prev;
}
}
ostream & operator<<(ostream & out, const Circular_tnodes_linked_list & p)
{
Circular_linked_list_tnodes *tmp;
for (tmp = p.head; tmp != nullptr && tmp != p.tail; tmp = tmp->next)
out << tmp->info << " ";
return out << p.tail->info;
}
Circular_tnodes_linked_list::~Circular_tnodes_linked_list()
{
for (Circular_linked_list_tnodes *p; !isempty();)
{
p = head->next;
delete head;
head = p;
}
}
// create_list.cpp
#include <iostream>
#include "linked_lists.h"
int main()
{
using namespace std;
//*********此处是循环链表——单节点测试代码********
Circular_tnodes_linked_list list4;
cout << list4.isempty() << endl;
list4.addtohead(1);
list4.addtohead(2);
list4.addtohead(3);
list4.addtohead(4);
list4.addtotail(5);
list4.addtotail(6);
list4.addtotail(7);
list4.addtotail(8);
list4.deletefromhead();
list4.deletefromhead();
list4.deletefromtail();
list4.deletefromtail();
list4.deleteselect(5);
list4.deleteselect(12);
cout << list4.inlist(1) << endl;
cout << list4.inlist(10) << endl;
cout << list4.isempty() << endl;
cout << list4 << endl;
//***********************************/
system("pause");
return 0;
}
参考资料:
1. C++数据结构与算法:https://item.jd.com/29739898993.html
本文介绍了使用C++实现循环链表的两种方法,一种是单指针方式,另一种是双指针方式,详细展示了如何构建、添加、删除节点及遍历链表,适用于需要高效访问链表头尾节点的应用场景。
4014

被折叠的 条评论
为什么被折叠?



