【Weiss】【第03章】练习3.4、3.5:有序链表求交、并
【练习3.4】
给定两个已排序的表L1和L2,只使用基本的表操作编写计算L1∩L2的过程。
【练习3.5】
给定两个已排序的表L1和L2,只使用基本的表操作编写计算L1∪L2的过程。
思路比较简单,测试代码如下,两道题比较相似,测试代码就放一起了。
#include <iostream>
#include "linklist.h"
using namespace std;
using namespace linklist;
template class List<int>;
int main(void)
{
List<int> primer; //原始链表
cout << "/*additem()*/" << endl;
primer.additem();
primer.additem();
primer.additem();
primer.additem();
primer.additem();
primer.additem();
primer.additem();
primer.additem();
primer.additem();
primer.additem();
primer.traverse();
cout << "\n/*end*/\n\n" << endl; //测试求交
cout << "/*intersection()*/" << endl;
List<int> odd;
odd.additem();
odd.additem();
odd.additem();
odd.additem();
odd.additem();
odd.additem();
odd.additem();
odd.additem();
odd.additem();
odd.additem();
odd.additem();
odd.additem();
odd.additem();
odd.additem();
odd.traverse();
cout <<"\n"<<flush;
odd.intersecton(primer);
odd.traverse();
cout << "\n/*end*/\n\n" << endl; //测试求并
cout << "/*join()*/" << endl;
List<int> natural;
natural.additem();
natural.additem();
natural.additem();
natural.additem();
natural.additem();
natural.traverse();
cout << endl;;
natural.join(primer);
natural.traverse();
cout << "\n/*end*/\n\n" << endl; system("pause");
}
主要思路就是两个链表同时前进并比较元素大小,在合适的节点处删除或插入节点,时间复杂度O(n)。
为了满足中途插入或删除的需求,在3.4处补充了一个最初没有的辅助删除操作,3.5补充了一个辅助插入操作。
练习3.4,求交代码如下:
//练习3.4新增,删除指定地址的下一个节点,如地址为nullptr,则删除头节点
template <typename T> bool List<T>::remove(Node<T>* pos)
{
if (length == )
{
cout << "No data!" << endl;
return false;
}
if (pos == nullptr)
{
pos = front;
front = front->next;
delete pos;
}
else
{
Node<T>* temp = pos->next;
pos->next = pos->next->next;
delete temp;
}
--length;
return true;
}
//练习3.4新增,计算两升序链表元素交集并直接覆盖在原链表上
template <typename T> void List<T>::intersecton(List<T> inorder)
{
//原表多保存一个prev以删除节点时传参用
Node<T>* curr = front;
Node<T>* prev = nullptr;
Node<T>* curr2 = inorder.front;
while (curr != nullptr && curr2 != nullptr)
{
//原表元素小于新表,删除原表元素
if (curr->data < curr2->data)
{
curr = curr->next;
remove(prev);
}
//新表元素大于原表,新表查看下一个节点
else if (curr2->data < curr->data)
curr2 = curr2->next;
//两表元素相等,指针共同后移,保留元素
else
{
prev = curr;
curr = curr->next;
curr2 = curr2->next;
}
}
//如果新链表结束后,原链表尾部还有元素,全部删除
while (curr != nullptr)
{
curr = curr->next;
remove(prev);
}
}
练习3.5,求并代码如下:
//练习3.5新增,增加一个节点于在指定地址的下一个节点,如地址为nullptr,则于头节点插入
template <typename T> bool List<T>::additem(const T &item, Node<T> *pos)
{
Node<T>* pnew = new Node<T>(item);
if (pos == nullptr)
{
pnew->next = front;
front = pnew;
}
else
{
pnew->next = pos->next;
pos->next = pnew;
}
++length;
return true;
}
//练习3.5新增,计算两升序链表元素并集并直接覆盖在原链表上
template <typename T> void List<T>::join(List<T> inorder)
{
Node<T>* curr = front;
Node<T>* prev = nullptr;
Node<T>* curr2 = inorder.front;
while (curr != nullptr && curr2 != nullptr)
{
//原链表元素小于新链表元素,原链表查看下一个节点
if (curr->data < curr2->data)
{
prev = curr;
curr = curr->next;
}
//新链表元素小于原链表元素,则插入一个带相同值的元素在curr前(即在prev后)
else if (curr2->data < curr->data)
{
additem(curr2->data, prev);
//因为是在prev指针【后】插入元素,为保证升序,插入后prev向后移动
if (prev == nullptr)
prev = front;
else
prev = prev->next;
curr2 = curr2->next;
}
//两元素相等,共同查看下一个节点
else
{
prev = curr;
curr = curr->next;
curr2 = curr2->next;
}
}
while (curr2 != nullptr)
{
additem(curr2->data, prev);
if (prev == nullptr)
prev = front;
else
prev = prev->next;
curr2 = curr2->next;
}
}
【Weiss】【第03章】练习3.4、3.5:有序链表求交、并的更多相关文章
- 【Weiss】【第03章】练习3.8:有序多项式求幂
[练习3.8] 编写一个程序,输入一个多项式F(X),计算出(F(X))P.你程序的时间复杂度是多少? Answer: (特例:P==0时,返回1.) 如果P是偶数,那么就递归计算((F(X))P/2 ...
- 【Weiss】【第03章】练习3.15:自调整链表
[练习3.15] a.写出自调整表的数组实现.自调整表如同一个规则的表,但是所有的插入都在表头进行. 当一个元素被Find访问时,它就被移到表头而并不改变其余的项的相对顺序. b.写出自调整表的链表实 ...
- 【Weiss】【第03章】练习3.12:单链表倒置
[练习3.12] a.编写一个非递归过程以O(N)时间反转单链表. b.使用常数附加空间编写一个过程以O(N)时间反转单链表. Answer: 这题的b貌似没啥意义,在a小题里直接用头插法,不断地将头 ...
- 【Weiss】【第03章】练习3.7:有序多项式相乘
[练习3.7] 编写一个函数将两个多项式相乘,用一个链表实现.你必须保证输出的多项式按幂次排列,并且任意幂次最多只有一项. a.给出以O(M2N2)时间求解该问题的算法. b.写一个以O(M2N)时间 ...
- 【Weiss】【第03章】练习3.6:有序多项式相加
[练习3.6] 编写将两个多项式相加的函数.不要毁坏输入数据.用一个链表实现. 如果这两个多项式分别有M项和N项,那么你程序的时间复杂度是多少? 两个按幂次升序的多项式链表,分别维护一个指针. 幂较小 ...
- 第03章 AOP前奏
第03章 AOP前奏 提出问题 ●情景:数学计算器 ●要求 ①执行加减乘除运算 ②日志:在程序执行期间追踪正在发生的活动 ③验证:希望计算器只能处理正数的运算 ●常规实现 ●问题 ○代码混乱:越来越多 ...
- 第03章_基本的SELECT语句
第03章_基本的SELECT语句 1. SQL概述 1.1 SQL背景知识 1946 年,世界上第一台电脑诞生,如今,借由这台电脑发展起来的互联网已经自成江湖.在这几十年里,无数的技术.产业在这片江湖 ...
- suse 12 二进制部署 Kubernetets 1.19.7 - 第03章 - 部署flannel插件
文章目录 1.3.部署flannel网络 1.3.0.下载flannel二进制文件 1.3.1.创建flannel证书和私钥 1.3.2.生成flannel证书和私钥 1.3.3.将pod网段写入et ...
- 【Weiss】【第03章】增补附注
基本上每章到增补附注这里就算是结束了. 根据设想,每章的这一篇基本上会注明这一章哪些题没有做,原因是什么,如果以后打算做了也会在这里补充. 还有就是最后会把有此前诸多习题的代码和原数据结构放整理后,以 ...
随机推荐
- python爬虫心得(第一天)
爬虫是什么? 我个人觉得用简单通俗的话来说就是在浏览网页的过程中将有价值的信息下载到本地硬盘或者是储存到数据库中的行为. 爬虫的基础认知 可以参考此链接:https://www.imooc.com/a ...
- 实现一个简易的HashMap
实现一个键的类型为int,值的类型为int的HashMap 输入一个T,表示操作次数: 之后每行接一个操作,可以包括插入.删除.修改.查询.清空.判断是否有这个键: 因为是刚学完随手敲的,所以功能粗糙 ...
- spring整合ehcache实现缓存
Spring 提供了对缓存功能的抽象:即允许绑定不同的缓存解决方案(如Ehcache),但本身不直接提供缓存功能的实现.它支持注解方式使用缓存,非常方便. spring本身内置了对Cache的支持,之 ...
- 云服务器——之Linux下安装tomcat
在上一篇文章中已经准备好了tomcat安装的基本环境jdk的安装,那么我们现在来记录tomcat的安装. 第一步:下载tomcat安装包 http://tomcat.apache.org/ 第二步:通 ...
- USB小白学习之路(11) Cy7c68013A驱动电路设计注意事项(转)
Cy7c68013A驱动电路设计注意事项 转自:http://group.chinaaet.com/116/79029#0-tsina-1-71467-397232819ff9a47a7b7e80a4 ...
- 这几个IDEA高级调试技巧,用完就是香
一个项目启动两次 测试分布式项目时,经常要一个项目启动2次,不用将一个项目打开多次启动,配置一下即可 1.点击Edit Configurations 2.勾选Allow parallel run 3. ...
- 【Mood】八上期末考
Final exam Day -30 平姐在班会上突然就说了一句,离期末考只有一个月了. 刚从体育节的气氛中脱离出来的我想了想,好像还真的是诶. 又努力地去想了想,好像不太慌张呢. Final ex ...
- Azure Devops/TFS测试管理(下)
紧接着 上篇 经过上篇折腾,我们已经有了: ①手工测试的流程规范 ②测试用例的管理 对于开发出身的我,我觉得一个项目上线流程应该主要瓶颈只能是开发本身,因为我认为最复杂过程应该就是开发,而肯定不能是测 ...
- 解决oninput事件在中文输入法下会取得拼音的值的问题
在做搜索等功能时,很多时候我们需要实时获取用户输入的值,而常常会得到类似 w'm 这样的拼音.为了解决这个问题,我在网上搜索了下相关问题,发现了两个陌生的事件:compositionstart 和 c ...
- CSS+DIV自适应布局
CSS+DIV自适应布局 1.两列布局(左右两侧,左侧固定宽度200px;右侧自适应占满) 代码如下: <!doctype html> <html> <head> ...