C++实现线性表的链式存储结构(循环链表)
循环链表是另一种形式的链式存储结构。它的特点是表中最后一个结点的指针域不再是空,而是指向首结点,整个链表形成一个环。
循环链表的特点(与单链表相比较):
- 没有指针域为NULL的结点;
- 在循环链表中,可以从任一结点出发沿指针域访问表中的所有结点;也就是说只要知道表中某一结点的地址,就可搜寻到所有其他结点的地址。
约瑟夫环是使用循环链表解决的最经典的题目,我会在之后的博客中更新相关的思路和代码。
本博客主要是循环链表的实现。
循环链表的示例:
- 循环链表为空时,head->next == head。
- 循环链表不为空时,尾结点指向首结点(rear->next == head->next),而不是NULL。
循环链表的基本操作:
-
插入:在表头、表尾、和第pos个位置插入数据
-
删除:删除表头、表尾和第pos个位置的数据
-
修改:修改表头、表尾和第pos个位置的数据
-
得到数据:得到表头、表尾和第pos个位置的结点和数据
-
查找:在循环链表中查找数据p,返回位置
-
计算长度:返回单链表的长度
-
打印
一、结点类的定义
template<class T>
class CircularLinkList;
template<class T>
class LinkNode {
friend class CircularLinkList<T>;
private:
T data;
LinkNode<T> *next;
public:
LinkNode() {
next = NULL;
}
explicit LinkNode(T p) {
data = p;
next = NULL;
}
LinkNode<T> &operator=(const LinkNode<T> *p) {
data = p->data;
next = p->next;
return *this;
}
};
二、循环链表类的定义
template<class T>
class CircularLinkList {
private:
LinkNode<T> *head;
LinkNode<T> *rear;
public:
CircularLinkList(); //构造函数
CircularLinkList(CircularLinkList<T> &list); //拷贝构造函数
~CircularLinkList(); //析构函数
void append_first(T p); //头插法,在循环链表头插入数据
void append_last(T p); //尾插法,在循环链表尾插入数据
bool append_pos(int pos, T p); //在循环链表第pos个位置插入数据
void pop_first(); //删除循环链表头数据
void pop_last(); //删除循环链表尾数据
bool pop_pos(int pos); //删除循环链表中第pos个数据
void change_first(T p); //修改循环链表头数据
void change_last(T p); //修改循环链表尾数据
bool change_pos(int pos, T p); //修改循环链表中第pos个数据
bool get_first_node(LinkNode<T> *&p); //得到循环链表头结点
bool get_last_node(LinkNode<T> *&p); //得到循环链表尾结点
bool get_pos_node(int pos, LinkNode<T> *&p); //得到循环链表中第pos个结点
bool get_first_data(T &p); //得到循环链表头数据
bool get_last_data(T &p); //得到循环链表尾数据
bool get_pos_data(int pos, T &p); //得到循环链表中第pos个数据
int search(T p); //返回循环链表中p相同的第一个元素的下标pos,若不存在则返回-1
bool isEmpty(); //判断循环链表是否为空
int length(); //返回循环链表的长度
void print(); //打印循环链表
void clear(); //清空循环链表
};
1. 基本函数(构造函数、析构函数、判空函数等)
//构造函数
template<class T>
CircularLinkList<T>::