#include<iostream> //循环双向链表
#include "LDLinkList.h"
#include "LDLinkList.cpp"
template<class Type>
class LinkNode { //节点类
public:
Type data; //数据域,存放数据
LinkNode<Type>* prior; //指针域,指向前一个节点
LinkNode<Type>* next; //指针域,指向后一个节点
};
template<class Type>
class LinkList { //链表类
private:
int length;
public:
LinkList();
void InitList(LinkNode<Type>*& L); //建立头节点
void CreateList(LinkNode<Type>*& L, Type arr[], int& len); //头插法建立循环单链表
bool ListEmpty(LinkNode<Type>*& L); //判断循环单链表是否为空
int ListLength(LinkNode<Type>*& L); //获取循环单链表长度
void DispList(LinkNode<Type>*& L) const; //输出循环单链表
bool GetElem(LinkNode<Type>*& L, int& locate, Type& e); //按照输入的数值查找循环单链表
bool LocateList(LinkNode<Type>*& L, Type& e, int& locate); //按照输入的元素值查找循环单链表
bool InsertList(LinkNode<Type>*& L, int& locate, Type& e); //将指定元素插入到执行位置
bool DeleteList(LinkNode<Type>*& L, int& locate, Type& e); //删除指定位置的元素并使用e接收要删除的元素值
void DestoryList(LinkNode<Type>*& L) const; //销毁循环单链表
~LinkList();
};
template<class Type>
LinkList<Type>::LinkList()
{
length = 0; //初始值设置为零
std::cout << "构造函数建立循环单链表对象完成!" << std::endl;
}
template<class Type>
void LinkList<Type>::InitList(LinkNode<Type>*& L)
{
L = new LinkNode<Type>;
L->prior = L; //将节点L的指针prior,next指向自身
L->next = L;
std::cout << "InitList建立头节点完成!" << std::endl;
}
template<class Type>
void LinkList<Type>::CreateList(LinkNode<Type>*& L, Type arr[], int& len)
{
LinkNode<Type>* pre;
int i;
length = len; //获取双链表的长度
for (i = 0;i < len;i++) {
pre = new LinkNode<Type>; //动态申请节点的存储空间
pre->data = arr[i];
pre->next = L->next; //将节点s插入到循环单链表上
L->next->prior = pre;
pre->prior = L;
L->next = pre;
}
std::cout << "CreateList建立循环双链表完成!" << std::endl;
}
template<class Type>
bool LinkList<Type>::ListEmpty(LinkNode<Type>*& L)
{
//返回值true说明节点L的next指针指向节点L本身,因此链表为空,否则非空
return (L->next == L);
}
template<class Type>
int LinkList<Type>::ListLength(LinkNode<Type>*& L)
{
return length;
}
template<class Type>
void LinkList<Type>::DispList(LinkNode<Type>*& L) const
{
LinkNode<Type>* pre = L;
if (L->next == L) //这是判断单链表是否还有其它节点
std::cout << "DispList检测到单链表此时只有一个头节点,无法输出!" << std::endl;
else {
while (pre->next != L) //找到最先插入的点
pre = pre->next;
while (pre != L) {
std::cout << pre->data << " ";
pre = pre->prior; //将指针pre迁移一位指向上一个节点
}
std::cout << "\n";//换行并清空缓冲区的内容
std::cout << "DispList输出循环链表完成!" << std::endl;
}
}
template<class Type>
bool LinkList<Type>::GetElem(LinkNode<Type>*& L, int& locate, Type& e)
{
LinkNode<Type>* pre = L;
int i = 0;
if (locate <= 0) {
std::cout << "GetELem检测到违法输入!" << std::endl;
return false;
}
while (i <= length - locate) {//将逻辑位置转换为单链表中的位置
i++;
pre = pre->next;
}
if (length - locate < 0) {//未查询到节点pre,查询越界(pre->next==L)
std::cout << "GetElem未查询到结果(越界)!" << std::endl;
return false;
}
else //此时在链表中查询到该节点pre(i>length-locate)
{
e = pre->data; //使用元素e接收查询的值
std::cout << "GetElem查询成功!" << std::endl;
return true;
}
}
template<class Type>
bool LinkList<Type>::LocateList(LinkNode<Type>*& L, Type& e, int& locate)
{
LinkNode<Type>* pre = L;
int i = 0;
while (pre->data != e && pre->next != L) {//该节点的data数据域存放的不是e,该节点不是最后一个节点
i++;
pre = pre->next;
}
if (pre->next == L) {//已经查询到最后一个节点
std::cout << "LocateList查询链表失败!(越界)" << std::endl;
return false;
}
else //说明在链表中查询到元素e
{
locate = length - i + 1;//元素的逻辑位置和在链表中的真实位置满足:逻辑位置+链表存储位置 = length+1
std::cout << "LocateList查询链表成功!" << std::endl;
return true;
}
}
template<class Type>
bool LinkList<Type>::InsertList(LinkNode<Type>*& L, int& locate, Type& e)//将元素e插入到指定位置
{
LinkNode<Type>* pre = L, * s;
int i = 0;
if (locate <= 0 || length - locate < 0) {
std::cout << "InsertList检测到违法输入!" << std::endl;
return false; //返回函数调用点
}
while (i <= length - locate) {//逻辑位置转换成链表中的实际位置,判断是否越界
i++;
pre = pre->next;
}
s = new LinkNode<Type>; //动态申请存储空间
s->data = e;
s->next = pre->next; //节点s插入到单链表中,需要修改四个指针
if(pre->next!=L) //判断节点L是否存在下一个节点
pre->next->prior = s;
pre->next = s;
s->prior = pre;
length++; //插入成功后更新循环链表长度
std::cout << "InsertList插入节点成功!" << std::endl;
return true;
}
template<class Type>
bool LinkList<Type>::DeleteList(LinkNode<Type>*& L, int& locate, Type& e)
{
LinkNode<Type>* pre = L;
int i = 0;
if (locate <= 0) {
std::cout << "DeleteList检测到违法输入!" << std::endl;
return false; //返回函数调用点
}
while (i < length - locate) {//逻辑位置转换成链表中的实际位置,判断是否越界
i++;
pre = pre->next;
}
if (length - locate < 0) {//若此时输入的locate小于链表长度,说明链表发生越界,删除失败
std::cout << "DeleteList插入失败(越界)!" << std::endl;
return false;
}
else//说明已经找到要删除的节点
{
pre->prior->next = pre->next;//删除这个节点
pre->next->prior = pre->prior;
e = pre->data;
delete pre;
length--;//删除后更新循环链表的长度
std::cout << "DeleteList删除节点成功!" << std::endl;
return true;
}
}
template<class Type>
void LinkList<Type>::DestoryList(LinkNode<Type>*& L) const
{
LinkNode<Type>* pre = L->next;
while (L->next != L) { //判断节点L的下一个节点是否为L
L->next = pre->next; //L的next指针指向要删除的节点的下一个节点
delete pre; //删除节点并将指针pre重置指向节点L的下一个节点
pre = L->next;
}
delete L;
std::cout << "DestoryList销毁链表成功!" << std::endl;
}
template<class Type>
LinkList<Type>::~LinkList<Type>()
{
std::cout << "析构函数释放循环单链表对象!" << std::endl;
}
int main() {
using std::cout;
using std::endl;
LinkNode<int>* L;
LinkList<int> obj;
int arr[]{ 1,2,3,4,5,7,8,9,10 };
int len = sizeof(arr) / sizeof(arr[0]);//获取数组的长度
int length = 0;
obj.InitList(L); //测试InitList函数接口的功能,同时获取此时链表的状态信息
length = obj.ListLength(L);
cout << "此时的循环链表长度length为:" << length << endl;
int BOOL = obj.ListEmpty(L);
cout << "ListEmpty的值为0说明链表非空,为1说明链表为空!" << endl;
cout << "BOOL = " << BOOL << endl;
obj.DispList(L);
cout << endl;
obj.CreateList(L, arr, len); //测试CreateList函数接口功能,同时获取此时链表的状态信息
length = obj.ListLength(L);
cout << "ListLength获取链表长度length为:" << length << endl;
BOOL = obj.ListEmpty(L);
cout << "ListEmpty的值为0说明链表非空,为1说明链表为空!" << endl;
cout << "BOOL = " << BOOL << endl;
obj.DispList(L);
cout << endl;
int locate = 0, e = 0; //测试GetElem函数接口
locate = 7;
obj.GetElem(L, locate, e);
cout << "GetElem查询单链表后查找到的元素e值为:" << e << "\n\n";
locate = 0, e = 8; //按照元素e的值查询循环单链表
obj.LocateList(L, e, locate); //测试LocateList函数接口
cout << "LocateList查询单链表后的locate值为:" << locate << "\n\n";
locate = 6, e = 6; //将元素6插入到链表的指定位置(逻辑位置)
obj.InsertList(L, locate, e);
len = obj.ListLength(L);
cout << "此时ListLength获取的链表长度length为:" << len << endl;
obj.DispList(L);
cout << endl;
locate = 10, e = 0; //删除链表中指定位置的元素
obj.DeleteList(L, locate, e); //测试DeleteList函数接口
cout << "DeleteList删除的节点值e为:" << e << endl;
len = obj.ListLength(L);
cout << "此时ListLength获取的链表长度length为:" << len << endl;
obj.DispList(L);
cout << endl;
obj.DestoryList(L);
return 0;
}
就离谱,我这段代码问题出现在DispList函数 身上,问题出现在执行InsertList函数后,这时的再执行双向循环链表就出错。这是错误信息
我实在不知道问题出在哪,Insert和DIsplis函数来来回回看了很多遍,求路过的大神给点意见,谢谢了哈