假期结束,看点题目。

第一题

问题

设顺序表用数组A[]表示,表中元素存储在数组下标1~m+n的范围内,前m个元素递增有序,后n个元素递增有序,设计一个算法,使得整个顺序表有序。
(1)给出算法的基本设计思想。
(2)根据设计思想,采用C或C++语言描述算法,关键之处给出注释。
(3)说明你所设计算法的时间复杂度和空间复杂度。

解答

(1)算法基本设计思想:
将数组A[]中的m+n个元素(假设元素为int型)看成两个顺序表,表L和表R。将数组当前状态看做起始状态,即此时表L由A[]中前m个元素构成,表R由A[]中后n个元素构成。要使A[]中m+n个元素整体有序只需将表R中的元素逐个插入表L中的合适位置即可。插入过程:取表
R中的第一个元素A[m+1]存入辅助变量temp中,让temp逐个与A[m],A[m-1],…,A[1]进行比较,当temp<A[j](1≤j≤m)时,将A[j]后移一位;否则将temp存入A[j+1]中。重复上述过程继续插入A[m+2],A[m+3],……,A[m+n],最终A[]中元素整体有序。

(2)算法描述

void Insert(int A[],int m,int n){int i,j;int temp;    //辅助变量,用来暂存待插入元素。for(i=m+1;i<=m+n;i++) {    //将A[m+1…m+n]插入到A[1…m]中。temp=A[i];for(j=i-1;j>=1&&temp<A[j];j--)A[j+1]=A[j];    //元素后移,以便腾出一个位置插入temp。A[j+1]=temp;    //在j+1位置插入temp。}
}

(3)算法时间和空间复杂度
①本题的规模由m和n共同决定。取最内侧循环中A[j+1]=A[j];这一句作为基本操作,其执行次数在最坏的情况下为:f(m,n)=(m+m+n-1)n/2=mn+n2/2–n/22
②算法额外空间中只有一个变量temp,因此空间复杂度为O(1)。

第二题

问题

已知递增有序的单链表A,B(A,B中元素个数分别为m,n且A,B都带有头结点)分别存储了一个集合,请设计算法以求出两个集合A和B的差集A-B(即仅由在A中出现而不在B中出现的元素所构成的集合)。将差集保存在单链表A中,并保持元素的递增有序性。

(1)给出算法的基本设计思想。
(2)根据设计思想,采用C或C++语言描述算法,关键之处给出注释。
(3)说明你所设计算法的时间复杂度。

解答

(1)算法基本设计思想:
只需从A中删去A与B中共有的元素即可。由于两个链表中元素是递增有序的所以可以这么做:设置两个指针p, q开始时分别指向A和B的开始结点。循环进行以下判断和操作,如果p所指结点的值小于q所指结点值,则p后移一位;如果q所指结点的值小于p所指结点的值,则q后移一位;如果两者所指结点的值相同,则删除p所指结点。最后p与q任一指针为NULL的时候算法结束。

(2)算法描述:

void Difference(LNode *&A, LNode *B) {LNode *p = A->next, *q = B->next; //p和q分别是链表A和B的工作指针。LNode *pre = A;LNode *r;while(p != NULL && q != NULL) {if(p->data < q->data) {pre = p;   //pre 为A中p所指结点的前驱结点的指针。p = p->next;  //A链表中当前结点指针后移。}else if (p->data > q->data)q = q->next;else {pre->next = p->next;    //B 链表中当前结点指针后移。r = p;    //处理A,B中元素值相同的结点,应删除。p = p->next;free(r);    // 删除结点。}}
}

(3)算法时间复杂度分析:
由算法描述可知,算法规模由m和n共同确定。算法中有一个单层循环,循环内的所有操作都是常数级的,因此可以用循环执行的次数作为基本操作执行的次数。可见循环执行的次数即为p, q两指针沿着各自链表移动的次数,考虑最坏的情况,即p, q都走完了自己所在的链表,循环执行m+n次。即时间复杂度为O(m+n)。

第三题

问题

设计一个算法,将顺序表中的所有元素逆置。

解答

两个变量i,j指示顺序表的第一个元素和最后一个元素,交换i,j所指元素,然后i向后移动一个位置,j向前移动一个位置,如此循环,直到i与j相遇时结束,此时顺序表L中的元素已经逆置。

void reverse(Sqlist &L) {  //L要改变,用引用型int i,j;int temp; //辅助变量,用于交换for(i=1,j=L.length;i<j;i++,j--) {  //当i与j相遇时循环结束temp=L.data[i];L.data[i]=L.data[j];L.data[j]=temp;}
}

注意:本题中 for 循环的执行条件要写成i < j 而不要写成i != j 。如果数组中元素有偶数个则 i 与 j 会出现下图所示状态,此时i 继续往右走,j 继续往左走,会互相跨越对方,循环不会结束。

第四题

问题

设计一个算法,从一给定的顺序表L中删除下标i到j(i≤j,包括i,j)之间的所有元素,假定i,j都是合法的。

解答

本题是顺序表删除算法的扩展,可以采用如下方法解决,从第j+1个元素开始到最后一个元素为止,用这之间的每个元素去覆盖从这个元素开始往前数第j-i+1个元素,即可完成删除i~j之间的所有元素。

本题代码如下:

void Delete(Sqlist &L,int i,int j) { //L要改变,用引用型。int k,l;l = j-i+1; //元素要移动的距离。for(k = j + 1;k <= L.length; k++) {L.data[k-l] = L.data[k]; //用第k个元素去覆盖它前边的第l个元素。}L.length -= l; //表长改变。
}

第五题

问题

有一个顺序表L,其元素为整型数据,设计一个算法,将L中所有小于表头元素的整数放在前半部分,大于的整数放在后半部分,数组从下表1开始存储。

解答

本题可以这样解决,先将L的第一个元素存于变量temp中,然后定义两个整型变量i,j。i从左往右扫描,j从右往左扫描。边扫描边交换。具体执行过程如下:

各步的解释如下:
①开始状态,temp = 2,i = 1; j = L.length
②j先移动,从右往左,边移动边检查j所指元素是否比2小,此时发现-1比2小,则执行L.data[i]=L.data[j];i++;(i中元素已经被存入temp所以可以直接覆盖,并且i后移一位,准备开始i的扫描)
③i开始移动,从左往右,边移动边检测,看是否i所指元素比2大,此时发现-7比2小,因此i在此位置是什么都不做。
④i继续往右移动,此时i所指元素为-3也比2小,此时什么都不做。
⑤i继续往右移动,此时i所指元素为5,比2大,因此执行L.data[j] = L.data[i]; j--(j中元素已被保存,j前移一位,准备开始j的扫描)
⑥j往左运动,此时j所指元素为6,比2大,j在此位置时,什么都不做。
⑦j继续往左移动,此时j==i,说明扫描结束。
⑧执行L.data[i] = temp;此时整个过程结束,所有比2小的元素被移到了2前边,所有比2大的元素被移到了2后边。

以上过程要搞清楚两点:
①i和j是轮流移动的,即当i找到比2大的元素时,将i所指元素放入j所指位置,i停在当前位置不,j开始移动。j找到比2小的元素,将j所指元素放在i所指位置,j停在当前位置不动,i开始移动如此交替直到i==j。
②每次元素覆盖(比如执行L.data[i] = L.data[j];)不会造成元素丢失,因为在这之前被覆盖位置的元素已经存入其他位置。由以上分析可写出如下算法:

void move(Sqlist &L) { //L要改变所以用引用型int temp;int i = 1,j = L.length;temp = L.data[i];while(i<j){/*关键步骤开始*/while(i < j&&L.data[j] > temp) j--; //j从左往右扫描,当来到第一个比temp小的元素时停止        ,并且每走一步都要判断i是否小于j,这个判断容易遗漏。if(i < j) { //检测看是否已仍满足i < j,这一步同样很重要L.data[i] = L.data[j]; //移动元素。i++; //i右移一位。}while(i < j&&L.data[i] < temp) i++; //与上边的处理类似。if(i < j) { //与上边的处理类似。L.data[j] = L.data[i]; //与上边的处理类似。j--;}/*关键步骤结束*/}L.data[i] = temp; //将表首元素放在最终位置。
}

数据结构学习笔记(六)链表算法题相关推荐

  1. 数据结构学习笔记之一 链表

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 原貼作者 ...

  2. 数据结构学习笔记——基数排序 | 排序算法总结

    目录 一.基数排序排序思想 二.基数排序算法分析 三.排序算法总结 (一)分类 (二)比较 (三)详细分析 一.基数排序排序思想 基数排序与前面的排序算法不一样,它不基于比较和移动元素来进行排序,而是 ...

  3. 大话数据结构学习笔记二:算法

    一 算法定义 算法是解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作. 二 算法的特性: 1 输入输出:算法具有零个或者多个输入,至少有一个或者多个输出. 2 ...

  4. 数据结构学习笔记(六):二叉树(Binary Tree)

    目录 1 背景知识:树(Tree) 2 何为二叉树(Binray Tree) 2.1 二叉树的概念与结构 2.2 满二叉树与完全二叉树 2.3 二叉树的三种遍历方式 3 二叉树及其遍历的简单实现(Ja ...

  5. 数据结构 - 链表 - 面试中常见的链表算法题

    数据结构 - 链表 - 面试中常见的链表算法题 数据结构是面试中必定考查的知识点,面试者需要掌握几种经典的数据结构:线性表(数组.链表).栈与队列.树(二叉树.二叉查找树.平衡二叉树.红黑树).图. ...

  6. Python数据结构学习笔记——链表:无序链表和有序链表

    目录 一.链表 二.无序链表 实现步骤分析 三.无序链表的Python实现代码 四.有序链表 实现步骤分析 五.有序链表的Python实现代码 结语 一.链表 链表中每一个元素都由为两部分构成:一是该 ...

  7. 数据结构学习笔记:实现链表

    数据结构学习笔记:实现链表 1.结点结构 结点结构是由数据域和指针域组成,数据域是存放数据的,而指针域存放下一结点的地址. 2.链表结构 通过数据域访问到我们要的数据,而通过指针域访问到当前结点以后的 ...

  8. 数据结构——常见链表算法题

    数据结构--常见链表算法题(C++运行) 本文介绍常见的有关链表的算法题,值得一提的是,该代码无需在力扣上,可在本地运行成功. 题目八道: 1.反转链表 2.移除链表中的重复节点 3.查找链表中的中间 ...

  9. 数据结构(C语言版)学习笔记2-单链表

    数据结构(C语言版)学习笔记2-单链表 1.单链表定义 typedef int ElemTypes; typedef struct node {ElemTypes data; //数据域struct ...

  10. 【学习笔记】网络流算法简单入门

    [学习笔记]网络流算法简单入门 [大前言] 网络流是一种神奇的问题,在不同的题中你会发现各种各样的神仙操作. 而且从理论上讲,网络流可以处理所有二分图问题. 二分图和网络流的难度都在于问题建模,一般不 ...

最新文章

  1. VictoriaMetrics如何运用?
  2. NHibernate.Profiler 使用教程
  3. GoEasy导入依赖的时候报错,包用不了,maven导包
  4. 单片机c语言慧尾灯编码,(参考)基于单片机的智能尾灯开发文档.doc
  5. PyTorch基础-交叉熵函数mnist数据集识别-04
  6. java里的字符流_javaIO流中字符流的应用
  7. python列表相关函数_python中列表(list)相关的函数
  8. HBase 基本Java API
  9. 北京市委书记蔡奇:加快拓展数字人民币应用全场景试点
  10. hibernate执行sql语句 查询 删除
  11. 配置豪华的 Windows 开发环境
  12. sqlserver存储过程加锁后怎么解锁_MySQL 的加锁处理,你都了解的一清二楚了吗?...
  13. 使用线程池管理线程!
  14. 让HTML标签title属性值换行
  15. CocosCreator之层级管理器
  16. 使用n切换node版本
  17. 网络爬虫-学习记录(三)使用Selenium并对去哪儿网站进行爬取
  18. 2016年9月学习总结与反思
  19. 查看ip命令 linux centos7,如何centos7查看ip(地址)命令?
  20. 计算机合成图像的过程码,专转本计算机习题

热门文章

  1. java bean验证_javaBean--登录验证
  2. mysql 表2符合表1_MYSQL-表1和表2中所有可能性的所有行
  3. matlab 柯西黎曼方程,【判断题】柯西-黎曼方程成立是函数解析的必要条件.
  4. linux多线程九宫格,项目实战:Qt九宫格图片资源浏览器(支持window、linux、兼容各国产系统,支持子文件夹,多选,全选,图片预览,行数与列数设置等)...
  5. python邮件的图片放在哪里_用python保存电子邮件中的嵌入图像
  6. Windows 10重装系统时,提示Windows只能安装到GPT磁盘的解决方法(更新于2021.4.28)
  7. java url 本地文件是否存在_我的应用程序知道URL中是否存在文件会一直停止[重复]...
  8. 深度学习编译:MLIR初步
  9. Linux中 C++ main函数参数argc和argv含义及用法
  10. 显卡、显卡驱动、CUDA、CUDA Toolkit、cuDNN 梳理