博客
关于我
【SEU 数据结构课笔记】 03 - 2021/03/15 - LaTeX Code of Assignment
阅读量:771 次
发布时间:2019-03-21

本文共 2517 字,大约阅读时间需要 8 分钟。

数据结构(2021春季)报告


Problem

使用前置列表(forward_list)合并两个无重复元素的集合L_a和L_b。将其排序后,再合并为L_c。分析时间和空间复杂度。

Main Ideas

要在前置列表中合并L_a和L_b,我编写了一个支持类似于std::forward_list的名称空间tvj的forward_list。由于L_a和L_b已经排序,L_c的元素应选择当前未合并最小的L_a和L_b中的元素。另外,需要检查是否存在重复元素,以确保不添加重复的元素。为此,我在调试模式下使用了merge函数,如果这两个列表未排序,将会先排序它们。不过在发布模式中,这一步被跳过了。

Core Code

TVJ_Forward_List.h

在我的GitHub仓库TVJ_Forward_List(链接如下)中可以找到与merge功能相关的函数定义。当前版本为v1.1,于2021年3月20日发布。

TVJ_Forward_List代码片段

template
bool forward_list(elem>&&elem)
::sorted(bool is_ascending){
if (size_ < 2) return true;
for (auto iter = cbegin(); iter + 1 != cend(); ++iter) {
if (*iter == *(iter + 1)) continue;
if ((*iter < *(iter+1)) ^ is_ascending) return false;
}
return true;
}

merge函数代码片段

template
void forward_list(elem>&&elem)
::merge(const forward_list& list_, bool is_ascending){
if (list_.empty()) return;
// 以下代码已被优化
// 与当前对象和待合并列表复制
// 检查排序状态并进行排序(调试模式)
auto first_1 = this->head;
auto end_1 = this->tail;
auto first_2 = list_.head;
auto end_2 = list_.tail;
auto i = first_1->succ;
auto j = first_2->succ;
auto h = this->head;
bool label = true;
size_t new_size = 0;
while (i && i != end_1 && j && j != end_2) {
if (i->data == j->data) {
h = h->succ = i;
i = i->succ;
j = j->succ;
label = true;
} else if ((i->data < j->data) ^ !is_ascending) {
h = h->succ = i;
i = i->succ;
label = true;
} else {
h = h->succ = j;
j = j->succ;
}
new_size++;
}
// 处理剩余的元素
while (i && i != end_1) {
h = h->succ = i;
i = i->succ;
new_size++;
}
while (j && j != end_2) {
h = h->succ = j;
j = j->succ;
new_size++;
}
// 设置尾部
tail = h->succ;
size_ = new_size;
}

Result and Analysis

结果

测试结果表明,list1和list3已经成功合并。下图展示了在Visual Studio 2019和Qt 6.0.0环境下的输出。

时间复杂度分析

设n1为当前列表的长度,n2为待合并列表的长度。

  • 发布模式:首先需要将待合并列表复制到新的列表中,这一步的时间复杂度为O(n2)。然后,将两个已排序的列表合并操作的时间复杂度为O(n1 + n2)。因此,整体时间复杂度为O(n1 + n2)。
  • 调试模式:除了完成发布模式的操作外,还需检查两列表是否排序。若未排序,需对这两列表分别排序,时间复杂度分别为O(n1 log n1)和O(n2 log n2)。因此,调试模式的最好时间复杂度为O(n1 + n2),最坏时间复杂度为O(n1 log n1 + n2 log n2)。

空间复杂度

所有操作均不使用额外的临时空间,因此空间复杂度为O(1)。


结论

合并操作本质上并不难,但实现前置列表则非常具有挑战性。编写如此复杂的数据结构需要投入众多时间和精力。在完成这项任务的过程中,我深入理解了内联类和异常生成式等C++特性,以及对STL代码的深刻洞察。特别是sort函数的实现,对我后续的数据结构学习起到了激励作用。通过这次任务,我不仅加深了对前置列表的理解,还为探索更多数据结构的奥秘奠定了基础。


附录

本报告使用LaTeX编写。更多信息,请访问我的CSDN博客或GitHub profiles页面。

转载地址:http://gpogz.baihongyu.com/

你可能感兴趣的文章
No resource identifier found for attribute 'srcCompat' in package的解决办法
查看>>
no session found for current thread
查看>>
No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android
查看>>
NO.23 ZenTaoPHP目录结构
查看>>
no1
查看>>
NO32 网络层次及OSI7层模型--TCP三次握手四次断开--子网划分
查看>>
NOAA(美国海洋和大气管理局)气象数据获取与POI点数据获取
查看>>
NoClassDefFoundError: org/springframework/boot/context/properties/ConfigurationBeanFactoryMetadata
查看>>
node exporter完整版
查看>>
Node JS: < 一> 初识Node JS
查看>>
Node Sass does not yet support your current environment: Windows 64-bit with Unsupported runtime(72)
查看>>
Node 裁切图片的方法
查看>>
Node+Express连接mysql实现增删改查
查看>>
node, nvm, npm,pnpm,以前简单的前端环境为什么越来越复杂
查看>>
Node-RED中Button按钮组件和TextInput文字输入组件的使用
查看>>
Node-RED中Switch开关和Dropdown选择组件的使用
查看>>
Node-RED中使用html节点爬取HTML网页资料之爬取Node-RED的最新版本
查看>>
Node-RED中使用JSON数据建立web网站
查看>>
Node-RED中使用json节点解析JSON数据
查看>>
Node-RED中使用node-random节点来实现随机数在折线图中显示
查看>>