【练习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:有序链表求交、并的更多相关文章

  1. 【Weiss】【第03章】练习3.8:有序多项式求幂

    [练习3.8] 编写一个程序,输入一个多项式F(X),计算出(F(X))P.你程序的时间复杂度是多少? Answer: (特例:P==0时,返回1.) 如果P是偶数,那么就递归计算((F(X))P/2 ...

  2. 【Weiss】【第03章】练习3.15:自调整链表

    [练习3.15] a.写出自调整表的数组实现.自调整表如同一个规则的表,但是所有的插入都在表头进行. 当一个元素被Find访问时,它就被移到表头而并不改变其余的项的相对顺序. b.写出自调整表的链表实 ...

  3. 【Weiss】【第03章】练习3.12:单链表倒置

    [练习3.12] a.编写一个非递归过程以O(N)时间反转单链表. b.使用常数附加空间编写一个过程以O(N)时间反转单链表. Answer: 这题的b貌似没啥意义,在a小题里直接用头插法,不断地将头 ...

  4. 【Weiss】【第03章】练习3.7:有序多项式相乘

    [练习3.7] 编写一个函数将两个多项式相乘,用一个链表实现.你必须保证输出的多项式按幂次排列,并且任意幂次最多只有一项. a.给出以O(M2N2)时间求解该问题的算法. b.写一个以O(M2N)时间 ...

  5. 【Weiss】【第03章】练习3.6:有序多项式相加

    [练习3.6] 编写将两个多项式相加的函数.不要毁坏输入数据.用一个链表实现. 如果这两个多项式分别有M项和N项,那么你程序的时间复杂度是多少? 两个按幂次升序的多项式链表,分别维护一个指针. 幂较小 ...

  6. 第03章 AOP前奏

    第03章 AOP前奏 提出问题 ●情景:数学计算器 ●要求 ①执行加减乘除运算 ②日志:在程序执行期间追踪正在发生的活动 ③验证:希望计算器只能处理正数的运算 ●常规实现 ●问题 ○代码混乱:越来越多 ...

  7. 第03章_基本的SELECT语句

    第03章_基本的SELECT语句 1. SQL概述 1.1 SQL背景知识 1946 年,世界上第一台电脑诞生,如今,借由这台电脑发展起来的互联网已经自成江湖.在这几十年里,无数的技术.产业在这片江湖 ...

  8. 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 ...

  9. 【Weiss】【第03章】增补附注

    基本上每章到增补附注这里就算是结束了. 根据设想,每章的这一篇基本上会注明这一章哪些题没有做,原因是什么,如果以后打算做了也会在这里补充. 还有就是最后会把有此前诸多习题的代码和原数据结构放整理后,以 ...

随机推荐

  1. springdatajpa 认识以及使用方式

    1.spingdatajpa是什么? Spring Data JPA 是 Spring 基于 ORM 框架.JPA 规范的基础上封装的一套JPA应用框架(即上述的:JPA的实现产品),可使开发者用极简 ...

  2. Nginx笔记总结十六:nginx优化指南

    1.高层的配置 worker_processes 定义了nginx对外提供web服务时的worker进程数 worker_rlimit_nofile 更改worker进程最大打开文件数量限制,如果没有 ...

  3. 吴裕雄--天生自然 R语言开发学习:中级绘图

    #------------------------------------------------------------------------------------# # R in Action ...

  4. 通过virt-manager给Windowsxp系统配置virtio驱动

    在虚拟机的detail上添加一个硬件设备. 下载virtio.iso文件,我使用的版本126,具体的virtio驱动放到了10.2上的itest的目录中,使用可以找. 在配置中,添加virtio硬盘. ...

  5. JavaScript闭包、Object对象

    JavaScript闭包 定义:闭包指一个拥有许多变量和绑定这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. function a(){ var i=0; function ...

  6. CentOS7安装Ceph

    CentOS 7 下安装Ceph-nautilus 本问主要记录在CentOS 7下如何安装Ceph-nautilus,安装过程中遇到的一些问题及解决方法. 实验准备 以下是本次实验所用到的机器(采用 ...

  7. JavaScript之三 - 语法

    1.block 一般就是{}包括起来的代码块,注意的是,js没有块作用域,但是有函数作用域,全局作用域. 2.var 1 var a = b = 1; 如: 123456 function () { ...

  8. 安卓权威编程指南 -笔记(19章 使用SoundPool播放音频)

    针对BeatBox应用,可以使用SoundPool这个特别定制的实用工具. SoundPool能加载一批声音资源到内存中,并支持同时播放多个音频文件.因此所以,就算用户兴奋起来,狂按按钮播放全部音频, ...

  9. Microsoft Translator:消除面对面交流的语言障碍

    ​ Translator:消除面对面交流的语言障碍" title="Microsoft Translator:消除面对面交流的语言障碍"> ​ James Simm ...

  10. 银行储蓄程序(C++,simple)

    */ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...