一、实验目的和要求
两个表合并成一个有序表。要求设计两种以上储存方式、两种以上处理流程方式。分析各代码性能。
要求:
1. 抽象数据类型独立实现。
2. 其它要求同作业-01要求。
二、实验环境
编译器:Vscode DevC++
系统:Windows10
CPU:i5-8265U@1.60GHz
三、实验内容
分别使用链表、顺序表存储数据,处理方式多种来解决。
四、实验过程
4.1 任务定义和问题分析
顺序表很简单 就是用数组存储即可
两个数组来存储两个表的内容,之后处理合并并排序,类似于之前的归并排序
链表的话,先建立链表结构,如果功能和数组一样,就可以很简单的兼容,要做到这一点,需要做到以下几个功能:
- 可以新建结点
- 可以查询某一个位置的结点的数据
- 可以删除某一位置结点
- 可以修改某一位置的结点
- 可以支持两个位置数据的替换
不过这样做的结果就是链表的优势不显,反而比数组更耗时
与普通数组相比,链表的优势:
- 可以删除某一位置的结点
- 可以在某一位置插入结点
4.2 数据结构的选择和概要设计
数组:
- 创建两个数组来存储数据
- 使用之前的排序算法对两个数组进行排序
- 创建两个函数 分别使用两种方式合并排序(一种是合并后排序,此为方法1;另一种是排着序合并,此为方法2)
链表:
- 先行完善一些功能
- 在读入的时候就进行插入排序
- 创建两个函数 分别使用两种方式合并排序(一种是新建一个链表,再将两个链表的元素向第三个里插入,此为方法3;另一种是将一个链表中的元素插入到另一个链表的元素中,此为方法4)
4.3 详细设计
方案一/二:
两个方案均是创建三个合适大小的数组作为存储容器
对于数据的读入我选择快读
并提供每个表的大小,方便读入
然后利用之前的归并排序代码应用在将两个表变有序中
之后进行两种方案的不同操作:
- 有序表合并成乱序表 再次排序
- 有序表有序合并成有序表
方案三/四:
完善链表的功能
在查看有关算法书籍后 舍弃结构体作为结点的方式
改用声明结点类
并尝试将类的定义和实现分离(失败)
最终做到将类的操作都集中到了.h文件当中
实现了初始化、析构、清空、获取长度、返回第i个结点、返回给定数值的结点、在第i个结点后插入新结点、删除第i个结点、获取第i个结点的数据、将新结点按数据从小到大插入、输出所有结点的数据的功能。
本次使用的链表是双向链表(没怎么利用上)
两个方案的共同点就是需要先创建两个类对象用来存储两个表的数据。
由于链表的性质,使得数据的排序在插入结点时就已经完成了
两个方案不同点在于:
- 不需要再创建类对象,直接将一个对象里的数据逐个提取并按序插入到另一个即可
- 需要再创建一个类对象,然后将两个类对象里的数据逐个提取,按序插入到新建类对象中。
方案2与方案1相比,耗费的空间大,但时间减小了;
方案3与方案2相比,空间上没有什么优势,但时间上较好。
五、测试及结果分析
5.1 实验数据
表一 | 表二 | 合并后 |
3 6 1 2 7 | 32 65 1 54 | 1 1 2 3 6 7 32 54 65 |
32 65 865 34 12 43 6 76 45 | 34 768 2378 23 78 23 56 | 6 12 23 23 32 34 34 43 45 56 65 76 78 768 865 2378 |
5.2 结果及分析
最优选择应该是方案三 既不会像使用数组存储数据那样浪费空间,又不会像方案四那样浪费时间。
六、实验收获
对链表的体会更加深刻了
在调试链表的时候出现了很多bug 不过已发现的都已修正
七、参考文献
《妙趣横生的算法》