问题描述
目的:使用C++模板设计单链表的抽象数据类型(ADT)。并在此基础上,使用单链表ADT的基本操作,设计并实现单链表的简单算法设计。
内容:(1)请使用模板设计单链表的抽象数据类型。(由于该环境目前仅支持单文件的编译,故将所有内容都集中在一个源文件内。在实际的设计中,推荐将抽象类及对应的派生类分别放在单独的头文件中。参考网盘中的ADT原型文件。)
(2)ADT的简单应用:使用该ADT设计并实现单链表应用场合的一些简单算法设计。
应用3:假设线性表A=(a1,a2,…,am),线性表B=(b1,b2,…,bn),现要求设计一个算法,使用带头结点的单链表存储结构,按照下列规则合并A、B为线性表C。即:A和B的元素间隔排列,且使用A和B的原存储空间,且B不再单独存在。输入中的单链表的长度不得在该算法中利用,仅作为建表使用。
参考函数原型:
template<class ElemType>
void Merge_L( LinkList<ElemType> &A, LinkList<ElemType> &B );
输入说明
第一行:单链表A的长度
第二行:单链表A的数据元素(数据元素之间以空格分隔)
第三行:单链表B的长度
第四行:单链表B的数据元素(数据元素之间以空格分隔)
输出说明
第一行:单链表A的遍历结果
第二行:单链表B的遍历结果
第三行:交叉归并后单链表A的遍历结果
(输入与输出之间以空行分隔)
输入范例
10
13 5 27 9 32 123 76 98 54 87
5
1 3 7 8 11
输出范例
13 5 27 9 32 123 76 98 54 87
1 3 7 8 11
13 1 5 3 27 7 9 8 32 11 123 76 98 54 87
思路分析
-
题目重点
- 将A和B合并新的线性表C
- 使用A和B的原来的存储空间
- A和B的元素交叉排列
- B不再单独存在
-
题目分析
-
同两个链表的连接,不同的是同时要遍历,详见单链表的顺序连接
-
注意元素是交叉,所以注定会出现等长或者一长一短的情况,需要进行分类讨论
-
-
打个比方,将这个交叉合并比作贪吃蛇吃球球
- Atemp是蛇
- Btemp->next是球球现在的位置,不能和蛇在一条道上,只会跑不过蛇,只能来回跳
- temp是球球即将跳的位置
-
图一:Atemp蛇头已经吃了13,Atemp = Atemp->next,Btemp->next已经生成了果实,Atemp蛇头准备下去吃了
- 图二:Atemp蛇头要吃球球,跳到了对岸,球球原先在的1的位置,球球Btemp又跳到了原先temp的位置,预定下一次跳的位置是Atemp蛇的嘴边
- 如此交替,直至球球身亡
- 因为吃掉了球球,球球本身就代表剩余的链表,所以不需要再对剩余的链表进行连接
伪代码
template<class ElemType>
void Merge_L( LinkList<ElemType> &A, LinkList<ElemType> &B )
{
LinkNode<ElemType> *ATemp = A.GetHead()->next;
//获取A的首节点,不是头结点
LinkNode<ElemType> *BTemp = B.GetHead();
//获取B的头结点,不是首节点
LinkNode<ElemType> *temp = NULL;
//中间指针变量值
//insert the element of B into A crossways
while(BTemp->next && ATemp)
{
temp = ATemp->next;
ATemp->next = BTemp->next;
BTemp->next = temp;
ATemp = ATemp->next;
}
}
分析与总结
- 这就像一个贪吃游戏,ATemp控制的是链表A,BTemp控制的是食物,上下相互跳动,A吃了一个就会消化一下,即指针向后遍历一个
- 判定条件需要注意,是ATemp为空或者BTtemp->next为空
如有疑问或者不妥之处,请在评论区留言,如果很急,请加扣扣651378276,希望我能解答