问题描述
目的:使用C++模板设计单链表的抽象数据类型(ADT)。并在此基础上,使用单链表ADT的基本操作,设计并实现单链表的简单算法设计。
内容:(1)请使用模板设计单链表的抽象数据类型。(由于该环境目前仅支持单文件的编译,故将所有内容都集中在一个源文件内。在实际的设计中,推荐将抽象类及对应的派生类分别放在单独的头文件中。参考网盘中的ADT原型文件。)
(2)ADT的简单应用:使用该ADT设计并实现单链表应用场合的一些简单算法设计。
应用:假设用单链表 A存储m个正整数,结点的结构为(data,next),且|data|<=N(N为正整数)。现要求设计一个时间复杂度尽可能高效的算法,对于链表A中的数据元素data的绝对值相等的结点,仅保留第一次出现的结点而删除其余绝对值相等的结点。
参考函数原型:
template<class ElemType>
void Delete_Equal_Node( LinkList<ElemType> &A, int N );
输入说明
第一行:单链表A的长度 限定值N (以空格分隔)
第二行:单链表A的数据元素(数据元素之间以空格分隔)
输出说明
第一行:单链表A的遍历结果
空行
第二行:提纯后单链表A的遍历结果
输入范例
5 30
21 -15 -15 -7 15
输出范例
21 -15 -15 -7 15
21 -15 -7
问题分析
- 问题重点
- 单链表A存m个正整数,并且|data|<= N(N为正整数)
- 时间复杂度尽可能低
- A中的绝对值相等的点
- 仅保留第一次出现的结点,而删除其他绝对值相等的结点
尝试一
-
尽可能低的时间复杂度,就意味着我可以使用空间去换时间
-
如果使用hash表,需要额外的空间,自己在函数中在建立一张0到N的数组,用来充当简单的hash表,以便快速查取相关的元素。
-
图一:以N=6作为样例,形成一个具有六个元素的数组,
- 图二
- 往下接着遍历,一边遍历,以边修改数组中相关的值
- 如果发现对应的列表中的值已经是1,那就删除这个结点
伪代码
void Delete_Equal_Node( LinkList<ElemType> &A, int N )
{
//create the simple hashtable and assign zero to all elements
hashtable[N] = {0};
LinkNode *temp = A.GetHead()
LinkNode *temp2 = NULL;
index = 0;
while(temp->next)
{
index = abs(temp->next->data);
if(hashtable[index] == 0)
{
//situation:the element does not exist
hashtable[index] = 1;
temp = temp->next;
}
else
{
//situation:the element does exist and delete the revelent element
temp2 = temp->next->next;
temp->next = temp2;
}
}
}
异常处理现场
- 首先删除结点,需要先获取待删除结点的前一个结点,才能有效的删除
- 修改:使用当前结点的下一个结点进行判定
分析与总结
- 关于数组的创建,你后面就写一个数字,后面所有的数字都会初始化为该数字
- 当遍历next结点的时候,删除结点的话,是不需要进行的迭代下一个结点的,因为下一个结点已经删除了,已经改变了
如果不妥或者疑惑,请在评论区留言,或者加本人的扣扣651378276线上讨论