【练习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. 转载-MAC Mysql中文乱码解决方法

    相关链接: http://www.siguoya.name/pc/home/article/235 如有,有问题可以留言.

  2. ZOJ-1163-The Staircases

    dp[i][j]表示i个砖头构成的最高台阶不高于j的楼梯数目 Accepted 1163 C++11 0 2280 #include "bits/stdc++.h" using n ...

  3. Caused by: com.alibaba.fastjson.JSONException: syntax error, expect {, actual [, pos 0, fastjson-version 1.2

    环境: vue.js 问题: 当添加评论时 重新查询数据刷新数据控制台异常Caused by: com.alibaba.fastjson.JSONException: syntax error, ex ...

  4. Java集合 - 明的博客

    "In this world there are only two tragedies. One is not getting what one wants, and the other i ...

  5. derby常用语法

    derby常用语法 以user表为例: 1.创建表 create table user (id int primary key,account varchar(5),name varchar(5),p ...

  6. LeetCode 刷题记录(1-5题)

    1 两数之和(题目链接) class Solution: # 一次哈希法 def twoSum(self, nums, target): """ :type nums: ...

  7. 29.eval函数

    eval 函数 eval() 函数十分强大 -- 将字符串 当成 有效的表达式 来求值 并 返回计算结果 123456789101112131415 # 基本的数学计算In [1]: eval(&qu ...

  8. loadrunner通过web的post请求方法测接口 2

    模拟APP发送请求给Cloud, 一般都是用户登录后.cloud会返回登录成功的消息并且返回一个cookie给app, app下次要做一些例如设置名称之类的工作,在请求消息里面会携带返回的cookie ...

  9. STM32 一个初始化EXTI的例子

    23 May 2017 » Hardware 注:STM32F407VGT6 with STM32F4 DSP and standard peripherals library v1.8.0 外部中断 ...

  10. 启动tomcat报错 Unable to process Jar entry [module-info.class] from Jar...[xxx.xx.jar!\] for annotations

    Java Web 项目tomcat启动报错module-info.class 从git 上面拉下的项目,运行报错. jdk.maven配置正常 tomcat启动遇见的问题: Unable to pro ...