#pragma once
#include <iostream>
template<typename T>
struct CircLinkNode {
T data;
CircLinkNode<T>* link;
CircLinkNode(CircLinkNode<T>* next = nullptr) :data(0), link(next) {}
CircLinkNode(T d, CircLinkNode<T>* next = nullptr) :data(d), link(next) {}
};
template<typename T>
class CircList
{
public:
CircList(); //构造函数
CircList(const T& x); //构造函数
CircList(CircList<T>& L); //拷贝构造
~CircList(); //析构函数
void makeEmpty(); //将链表置空
int Length()const; //计算循环链表长度
bool IsEmpty() { return first->link == first ? true : false; }
//判表空否
CircLinkNode<T>* getHead()const; //返回附加头结点地址
void setHead(CircLinkNode<T>* p); //设置附加头结点地址
CircLinkNode<T>* Search(T x); //搜索含数据x的元素
CircLinkNode<T>* Locate(int i)const; //搜索第i个元素的地址
bool getData(int i, T& x)const; //取出第i个元素的地址
void setData(int i, T& x); //用x修改第i个元素的值
bool Insert(int i, T& x); //在第i个元素后插入x
bool Remove(int i, T& x); //删除第i个元素,x返回该元素的值
void output(); //输出
CircList<T>& operator=(CircList<T>& L); //重载运算符=
void inputFront(T endTag); //前插法建立单链表
void inputRear(T endTag); //后插法建立单链表
private:
CircLinkNode<T>* first, * last; //头指针,尾指针
};
template<typename T>
inline CircList<T>::CircList()
{
first = new CircLinkNode<T>;
first->link = first;
last = first;
}
template<typename T>
inline CircList<T>::CircList(const T& x)
{
first = new CircLinkNode<T>(x);
first->link = first;
last = first;
}
template<typename T>
inline CircList<T>::CircList(CircList<T>& L)
{
//拷贝构造函数
T value;
CircLinkNode<T>* srcptr = L.getHead(); //被赋值表的附加头结点地址
CircLinkNode<T>* destptr = first = new CircLinkNode<T>;
while (srcptr->link != L.first) //逐个结点复制
{
value = srcptr->link->data;
destptr->link = new CircLinkNode<T>(value);
destptr = destptr->link;
srcptr = srcptr->link;
}
last = srcptr;
destptr->link = first;
}
template<typename T>
inline CircList<T>::~CircList()
{
makeEmpty();
if (first != nullptr) delete first;
}
template<typename T>
inline void CircList<T>::makeEmpty()
{
//将链表置位空表
CircLinkNode<T>* q;
while (first->link != first)
{
q = first->link;
first->link = q->link;
delete q;
}
last = first;
}
template<typename T>
inline int CircList<T>::Length() const
{
//计算带附加头结点的单链表的长度
CircLinkNode<T>* p = first->link;
int count = 0;
while (p != first) //循链扫描,寻找链尾
{
p = p->link;
count++;
}
return count;
}
template<typename T>
inline CircLinkNode<T>* CircList<T>::getHead() const
{
return first;
}
template<typename T>
inline void CircList<T>::setHead(CircLinkNode<T>* p)
{
CircLinkNode<T>* current = first;
while (current->link != first)
{
if (current->link == p) break; //循链找p指针
else current = current->link;
}
first = current->link;
last = current;
}
template<typename T>
inline CircLinkNode<T>* CircList<T>::Search(T x)
{
//在表中搜索含数据x的节点,搜索成功时函数返回该节点地址;否则返回first值。
CircLinkNode<T>* current = first->link;
while (current != first)
{
if (current->data == x) break; //循链找含x结点
else current = current->link;
}
return current;
}
template<typename T>
inline CircLinkNode<T>* CircList<T>::Locate(int i) const
{
//定位函数。返回表中第i个元素的地址。若i<0或i超过表中结点个数,则返回first。
if (i < 0) return first; //i不合理
CircLinkNode<T>* current = first->link;
int k = 1;
while (current != first && k < i) //循链找第i个结点
{
current = current->link;
k++;
}
return current; //返回第i个结点地址,若返回first,表示i值太大
}
template<typename T>
inline bool CircList<T>::getData(int i, T& x) const
{
//取出链表中第i个元素的值。
if (i <= 0) return false; //i值太小
CircLinkNode<T>* current = Locate(i);
if (current == first) return false; //i值太大
else
{
x = current->data;
return true;
}
}
template<typename T>
inline void CircList<T>::setData(int i, T& x)
{
//给链表中的第i个元素赋值x。
if (i <= 0) return; //i值太小
CircLinkNode<T>* current = Locate(i);
if (current == first) return; //i值太大
else current->data = x;
}
template<typename T>
inline bool CircList<T>::Insert(int i, T& x)
{
//将新元素x插入在链表中第i个结点之后。
CircLinkNode<T>* current = Locate(i);
if (current == first) return false; //插入不成功
CircLinkNode<T>* newNode = new CircLinkNode<T>(x);
if (newNode == nullptr)
{
std::cerr << "存储分配错误!" << std::endl;
exit(1);
}
newNode->link = current->link;
current->link = newNode;
if (newNode->link == first) last = newNode;
return true; //插入成功
}
template<typename T>
inline bool CircList<T>::Remove(int i, T& x)
{
//将链表中的第i个元素删去,通过引用型参数x返回该元素的值。
CircLinkNode<T>* current = Locate(i - 1);
if (current == first || current->link == first) return false;
//删除不成功
CircLinkNode<T>* del = current->link; //重新拉链,将被删结点从链中摘下
current->link = del->link;
x = del->data;
delete del; //取出被删结点中的数据值
if (current->link == first) last = current;
return true;
}
template<typename T>
inline void CircList<T>::output()
{
//循环链表的输出函数:将循环链表中所有数据按逻辑顺序输出到屏幕上。
std::cout << "链表中的元素为: ";
CircLinkNode<T>* current = first->link;
while (current != first)
{
std::cout << current->data << " ";
current = current->link;
}
std::cout << std::endl;
}
template<typename T>
inline CircList<T>& CircList<T>::operator=(CircList<T>& L)
{
//重载函数:赋值操作,形式如 A = B,其中 A 是调用此操作的List对象,B 是参数表中的
//引用型参数L结合的实参。
makeEmpty();
T value;
CircLinkNode<T>* srcptr = L.getHead(); //被复制表的附加头结点地址
CircLinkNode<T>* destptr = first = new CircLinkNode<T>;
while (srcptr->link != L.first) //逐个结点复制
{
value = srcptr->link->data;
destptr->link = new CircLinkNode<T>(value);
destptr = destptr->link;
srcptr = srcptr->link;
}
destptr->link = first;
last = destptr;
return *this; //返回操作对象地址
}
template<typename T>
inline void CircList<T>::inputFront(T endTag)
{
//endTag是约定的输入序列结束的标志。如果输入序列是正整数,endTag可以是0或负数;
//如果输入序列是字符,endTag可以是字符集中不会出现的字符,如"\0"。
CircLinkNode<T>* newNode;
T val;
makeEmpty();
std::cin >> val;
while (val != endTag)
{
newNode = new CircLinkNode<T>(val); //创建新结点
if (newNode == nullptr)
{
std::cerr << "存储分配错误!" << std::endl;
exit(1);
}
newNode->link = first->link;
first->link = newNode; //插入到表最前端
if (last == first)
{
last = newNode;
}
std::cin >> val;
}
}
template<typename T>
inline void CircList<T>::inputRear(T endTag)
{
//endTag是约定的输入序列结束的标志
CircLinkNode<T>* newNode;
T val;
makeEmpty();
std::cin >> val;
while (val != endTag) //last指向表尾
{
newNode = new CircLinkNode<T>(val);
if (newNode == nullptr)
{
std::cerr << "存储分配错误!" << std::endl;
exit(1);
}
last->link = newNode;
last = newNode;
std::cin >> val; //插入到表末端
}
last->link = first;
}
循环链表模板类
最新推荐文章于 2024-05-31 12:03:11 发布