单链表ADT模板简单应用算法设计:2个单链表的交叉归并(手画图片讲解)

84 篇文章 5 订阅
67 篇文章 2 订阅
问题描述

目的:使用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,希望我能解答

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值