【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章】增补附注
基本上每章到增补附注这里就算是结束了. 根据设想,每章的这一篇基本上会注明这一章哪些题没有做,原因是什么,如果以后打算做了也会在这里补充. 还有就是最后会把有此前诸多习题的代码和原数据结构放整理后,以 ...
随机推荐
- springdatajpa 认识以及使用方式
1.spingdatajpa是什么? Spring Data JPA 是 Spring 基于 ORM 框架.JPA 规范的基础上封装的一套JPA应用框架(即上述的:JPA的实现产品),可使开发者用极简 ...
- Nginx笔记总结十六:nginx优化指南
1.高层的配置 worker_processes 定义了nginx对外提供web服务时的worker进程数 worker_rlimit_nofile 更改worker进程最大打开文件数量限制,如果没有 ...
- 吴裕雄--天生自然 R语言开发学习:中级绘图
#------------------------------------------------------------------------------------# # R in Action ...
- 通过virt-manager给Windowsxp系统配置virtio驱动
在虚拟机的detail上添加一个硬件设备. 下载virtio.iso文件,我使用的版本126,具体的virtio驱动放到了10.2上的itest的目录中,使用可以找. 在配置中,添加virtio硬盘. ...
- JavaScript闭包、Object对象
JavaScript闭包 定义:闭包指一个拥有许多变量和绑定这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. function a(){ var i=0; function ...
- CentOS7安装Ceph
CentOS 7 下安装Ceph-nautilus 本问主要记录在CentOS 7下如何安装Ceph-nautilus,安装过程中遇到的一些问题及解决方法. 实验准备 以下是本次实验所用到的机器(采用 ...
- JavaScript之三 - 语法
1.block 一般就是{}包括起来的代码块,注意的是,js没有块作用域,但是有函数作用域,全局作用域. 2.var 1 var a = b = 1; 如: 123456 function () { ...
- 安卓权威编程指南 -笔记(19章 使用SoundPool播放音频)
针对BeatBox应用,可以使用SoundPool这个特别定制的实用工具. SoundPool能加载一批声音资源到内存中,并支持同时播放多个音频文件.因此所以,就算用户兴奋起来,狂按按钮播放全部音频, ...
- Microsoft Translator:消除面对面交流的语言障碍
Translator:消除面对面交流的语言障碍" title="Microsoft Translator:消除面对面交流的语言障碍"> James Simm ...
- 银行储蓄程序(C++,simple)
*/ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...