// 2_a4.cpp -- 删除单链表中的连续一段的内容
/**
* 程序要求:
* 1. 写一个函数DeleteRange删除单链表中结点的值在low 和high之间的结点(low和high的值是多少可自由设计)。
* 2. 并且要在程序中验证其功能实现。(可在实验1的第3题的基础上增加此功能)。
* 3. 此题的源程序保存为 2_a4.cpp。
*/
/**
* 程序分析:
* 1. 该程序要求实现的功能只有两个,删除中间的值,删除一段值。
* 2. 虽然只有一个操作,但是必须得创建一个简单的单链表,其中单链表的需要包括以下几个功能:
* 3. 其中包括,构造函数,添加函数,删除函数。
* 4. 至于添加函数,因为不是主要检测的功能,这时只需要写一个简单的尾插入操作即可。
* 5. 除此之外,为了检测,还需要一个打印函数,用以遍历整个链表作检测。
*/
#include <iostream>
using std::cout;
template<typename elem>
class anote
{
public:
elem data;
anote *next;
public:
anote(elem d, anote * n = NULL):data(d), next(n){}
anote(anote * n = NULL): next(n){}
};
template <typename elem>
class alink:public anote<elem>
{
private:
// length
int leftsize;
int maxsize;
// pointer
anote<elem> *fence;
anote<elem> *tail;
anote<elem> *head;
void init(); // 创建一个带头结点的构造函数
bool appendhelp(const elem &);
bool deletehelp(elem delElem);
public:
alink():leftsize(0),maxsize(0) {init();}
void append(const elem &);
void del(const elem &);
bool DeleteRange(signed int low, signed int high);
void printall();
};
template<typename elem>
void alink<elem>::init()
{
head = new anote<elem>;
fence = head;
tail = head;
return;
};
// 尾插入操作
template <typename elem>
void alink<elem>::append(const elem & appElem)
{
if (!appendhelp(appElem))
{
cout << "\n插入错误,请检查操作。\n";
return;
}
else
cout << "\n恭喜,插入 " << appElem << " 元素成功。\n";
return;
}
template<typename elem>
bool alink<elem>::appendhelp(const elem & appElem)
{
if ( (tail -> next = new anote<elem>(appElem, tail -> next)) == NULL )
return false;
else
++maxsize;
return true;
}
// 删除操作
template <typename elem>
bool alink<elem>::deletehelp(elem delElem)
{
// 开始遍历寻找元素
for (fence = head, leftsize = 1; fence -> next != NULL; fence = fence -> next, ++leftsize)
{
if (fence -> next -> data == delElem)
{
anote<elem>* temp = fence -> next;
fence -> next = fence -> next -> next;
delete temp;
--maxsize;
return true;
}
}
return false;
}
template <typename elem>
void alink<elem>::del(const elem & delElem)
{
if (deletehelp(delElem) == false)
cout << "未找到元素或者是空表,删除失败!";
else
cout << "已成功删除元素。";
return;
}
template <typename elem>
bool alink<elem>::DeleteRange(signed int low, signed int high) // 以下标为准删除开区间
{
low++;
if ( 0 == maxsize)
{
cout << "该表为空,请先插入元素。";
return false;
}
static_cast<signed> (maxsize);
if (low < 0 && high > maxsize + 1) // 删除区间范围设定为-1到最大值加1(不删除 low 和 high 两个点)
{
cout << "你的输入有误,请重新输入删除区间。";
return false;
}
signed t = low; // 计算出最小值至零的距离
fence = head; // 因为删除的是开区间,所以先将区间移动一格
while (t > 0) // 将fence移动至最小值的开始范围
{
fence = fence -> next;
--t;
}
signed i = high - low;
for (; fence -> next != NULL && i > 0; --i)
{
anote<elem>* temp = fence -> next;
fence -> next = fence -> next -> next;
delete temp;
--maxsize;
}
return true;
}
// 显示操作
template <typename elem>
void alink<elem>::printall()
{
cout << "\n\n该表中共有 " << maxsize << " 个元素:\n";
for (fence = head, leftsize = 1; fence -> next != NULL; fence = fence -> next, ++leftsize)
{
cout << "第 " << leftsize << " 个元素是: " << fence -> next -> data;
cout << "\n";
}
cout << "\n";
return;
}
int main()
{
// 第一个功能的测试:删除中间的值
cout << "0.开始测试功能: " ;
alink<char> test;
test.printall();
cout << "\n\n1.正在插入字符 a b c d e f.";
test.append('a');
test.append('b');
test.append('c');
test.append('d');
test.append('e');
test.append('f');
test.printall();
cout << "\n\n2.插入字符成功.\n";
// 按以下顺序删除字符 b,d,c,e,f,a,每次删除后遍历链表。
cout << "\n\n3.按以下顺序删除字符 b,d,c,e,f,a,每次删除后遍历链表。\n";
cout << "\n01.正在删除字符 b.";
test.del('b');
test.printall();
cout << "\n02.正在删除字符 d.";
test.del('d');
test.printall();
cout << "\n03.正在删除字符 c.";
test.del('c');
test.printall();
cout << "\n04. 正在删除不存在于链表的字符g.";
test.del('g');
test.printall();
cout << "\n05.正在删除字符 e.";
test.del('e');
test.printall();
cout << "\n06.正在删除字符 f.";
test.del('f');
test.printall();
cout << "\n07.正在删除字符 a.";
test.del('a');
test.printall();
cout << "\n08. 正在删除不存在于链表的字符g.";
test.del('g');
test.printall();
// 第二个功能的测试:删除下标之间的值
cout << "\n\n5. 再次插入字符 a b c d e f.";
test.append('a');
test.append('b');
test.append('c');
test.append('d');
test.append('e');
test.append('f');
test.printall();
cout << "\n\n6.插入字符成功.\n";
cout << "\n\n测试删除一段数据的功能:(以下标为准)第1个至第3个:";
test.DeleteRange(-1, 3);
test.printall();
cout << "\n\n测试删除一段数据的功能:(以下标为准)未尾那两个:";
test.DeleteRange(0,3);
test.printall();
cout << "\n\n测试删除一段数据的功能:(以下标为准)第一个:";
test.DeleteRange(-1,1);
test.printall();
cout << "\n\n7. 删除功能测试完毕!\n";
system("pause");
cout << "退出程序中...";
return 0;
}