算法描述:

  在《啊哈算法》上有介绍模拟链表的实现。链表这种数据结构可以通过数组来实现,我们需要两个数组,其中一个数组data存放数据,即数据域。另外一个数组right用来存放每一个数的右边的数的位置,即指针域。

  在上图中,列如data[3]的下一个元素是data[4],下标为4 ,所以right[3]的值为4。又因为data[9]后没有元素,所以right[9]的值用0表示。
  如果我们要在data[4]数字8之前插入数字6,只需将6放到data数组末尾data[10],接下来将right[3]指向10,将right[10]指向4。

算法实现(上):

代码参考了《啊哈算法》上的实现,但实际上书上的代码是有问题的。

/*核心思路:
查找是否存在一个节点的下一个节点的数据大于待插入的节点,即data[right[t]]>data[len]
如果找到了,就修改right指针域。最后根据right指针域打印其数据域的值
*/
#include <stdio.h>
int data[101];
int right[101];//每个节点都有一个指针域,所以这里的数组长度要和data数组一样长
int main(){/*n为用户首次录入的节点总数,用于控制初始化节点时的循环次数len为当前节点总数,为方便操作,data[0]和right[0]不放内容,从下标1开始遍历,因此data[len]就是最后一个元素*/int n,i,len,t;scanf("%d",&n);//初始化数组datafor(i = 1;i<=n;i++){scanf("%d",&data[i]);}len = n;//初始化数组rightfor(i = 1;i<=n;i++){if(i!=n){right[i] = i+1;}else{right[i] = 0;//用0表示没有下一个元素}}//在data的末尾添加一个数len++;scanf("%d",&data[len]);/*通过遍历指针域,当找到某个节点的数据值大于插入的节点data[len]时,调整指针域的指向。直到指针域遍历完成为止*/t = 1;while(t!=0){if(data[right[t]]>data[len]){right[len] = right[t];right[t] = len;break; }t = right[t];}t = 1;while(t!=0){printf("%d ",data[t]);t = right[t];}//等待用户键盘录入,以起到暂停程序目的getchar();getchar();return 0;
}

程序验证:

第一组:
3
1 3 5
4
输出:1 3 4 5
第二组:
3
1 3 5
7
输出:1 3 5
第三组:
1
3
1
输出:3

测试发现,当用户要插入的数据小于data[1]或者大于最后一个数时,结果输出有误。
结合下面的代码段和这张图可知,当待插入数小于第一个数时,程序是将data[2]和插入数据进行比较;若是待插入的数大于最后一个数,当程序执行到right[t]==0时,由于data[0]未定义,程序也将不会进入if语句段修改其指针域。

    t = 1;while(t!=0){if(data[right[t]]>data[len])

算法修正

既然当待插入数大于最后一个数时,没有进入if(data[right[t]]>data[len])语句块,那么只需做一个标记,当未进入该语句块后,就修改最后一个数和倒数第二个数的指针域。
当插入数小于第一个数时,比如对于下面这种情况,由于right数组表示的是指向下一个节点的值,所以直接更改right[1]的值并不正确。

后来想到了可以添加一个头节点,即添加一个right[0],这样当插入数小于第一个数时,只需修改right[0]和right[len]两个指针域即可。

算法实现(下):

/*
核心思路:查找是否存在一个节点的下一个节点的数据大于待插入的节点,即data[right[t]]>data[len]
如果找到了,就修改right指针域。最后根据right指针域打印其数据域的值
*/
#include <stdio.h>
int data[101];
int right[101];//每个节点都有一个指针域,所以这里的数组长度要和data数组一样长
int main(){/*n为用户首次录入的节点总数,用于控制初始化节点时的循环次数len为当前节点总数,为方便操作,data[0]和right[0]不放内容,从下标1开始遍历,因此data[len]就是最后一个元素*/int n,i,len,t;int flag = 1;scanf("%d",&n);//初始化数组datafor(i = 1;i<=n;i++){scanf("%d",&data[i]);}len = n;//初始化数组rightfor(i = 0;i<=n;i++){if(i!=n){right[i] = i+1;}else{right[i] = 0;//用0表示没有下一个元素}}//在data的末尾添加一个数len++;scanf("%d",&data[len]);/*通过遍历指针域,当找到某个节点的数据值大于插入的节点data[len]时,调整指针域的指向。直到指针域遍历完成为止*/t = 1;//对插入节点小于第一个节点的情况做特殊处理。(这里放在if..else里是出于无需再走循环的目的)if(data[len]<data[1]){right[0] = len;right[len] = 1;}else{while(t!=0){if(data[right[t]]>data[len]){flag = 0;right[len] = right[t];right[t] = len;break; }t = right[t];}//插入节点大于最后一个节点的情况 if(flag == 1){right[len] = 0;/*这里只做简单处理,也可以查找right[t]==0的节点修改其指针域,只需在上面循环中加入if(right[t]==0){temp = t;}这里再改成right[temp] = len;*/right[len-1] = len;}}//t为right[0]头节点指向的首节点的下标 t = right[0];while(t!=0){printf("%d ",data[t]);t = right[t];}//等待用户键盘录入,以起到暂停程序目的getchar();getchar();return 0;
}

程序验证:

第一组:
3
1 3 5
4
输出:1 3 4 5
第二组:
3
1 3 5
7
输出:1 3 5 7
第三组:
1
3
1
输出:1 3

修正《啊哈算法》上模拟链表算法的错误相关推荐

  1. 已知一个带有表头的单链表,结点结构为data-link,假设该链表只给出了头指针list。在不改变链表的前提下,请设计一个尽可能高效的算法,查找链表中倒数第k个位置上的结点(k为正整数)。

    今天和大家分享一道2009年代码为408的一道真题: 已知一个带有表头的单链表,结点结构为data-link,假设该链表只给出了头指针list.在不改变链表的前提下,请设计一个尽可能高效的算法,查找链 ...

  2. 操作系统课设之虚拟内存页面置换算法的模拟与实现

    前言 课程设计开始了,实验很有意思,写博客总结学到的知识 白嫖容易,创作不易,学到东西才是真 本文原创,创作不易,转载请注明!!! 本文链接 个人博客:https://ronglin.fun/arch ...

  3. 操作系统学习之用C语言模拟LRU算法

    前言 LRU算比较经典,而且考的也比较多,LRU算法全称Least Recently Used,译为最近最少使用.用C模拟一下吧. Buddy算法:操作系统学习之用C语言模拟伙伴(Buddy)算法 F ...

  4. 基于自适应算法和增量式PID算法的模拟直升飞机控制系统

    基于自适应算法和增量式PID算法的模拟直升飞机控制系统 文章目录 基于自适应算法和增量式PID算法的模拟直升飞机控制系统 控制系统硬件 单片机系统 传感器系统介绍 直升机模拟系统介绍 系统模块介绍 A ...

  5. 用循环首次适应算法、最佳适应算法和最坏适应算法,模拟可变分区存储管理,实现对内存区的分配和回收管理

    湖南师范大学 信息科学与工程学院 操作系统课程实验报告 实验项目名称: 可变分区存储管理 题目 实验一.可变分区存储管理 一.实验目的: 加深对可变分区存储管理的理解: 提高用C语言编制大型系统程序的 ...

  6. 41. 盘点那些必问的数据结构算法题之链表

    盘点那些必问的数据结构算法题之链表 0 概述 1 定义 2 基本操作 3 链表相关面试题 3.1 链表逆序 3.2 链表复制 3.3 链表合并 3.4 链表相交判断 3.5 判断链表是否存在环 3.6 ...

  7. 【数据结构与算法】 01 链表 (单链表、双向链表、循环链表、块状链表、头结点、链表反转与排序、约瑟夫环问题)

    一.线性表 1.1 概念与特点 1.2 线性表的存储结构 1.3 常见操作 1.4 应用场景 二.链表 2.1 链表简介 2.2 单向链表(单链表) 2.21 基本概念 2.22 单链表基本操作 2. ...

  8. 操作系统: 最佳适配算法和邻近适配算法的模拟实现(内存分配算法)

    实现动态分区的分配算法. (1) 最佳适配算法:选择内存空闲块中最适合进程大小的块分配. (2) 邻近适配算法:从上一次分配的地址开始查找符合要求的块,所查找到的第一个满足要求的空闲块就分配给进程. ...

  9. 为了OFFER,花了几个小时,刷下Leetcode链表算法题

    @Author:Runsen @Date:2020/9/13 链表是我这辈子的痛啊,每次学到链表,就往往不会,就没有继续学下去.现在大四不能继续让这个链表阻碍我了.现在基本是重刷数据结构和算法,毕竟笔 ...

最新文章

  1. DR模式 mysqlABB读写分离
  2. laytpl遍历实体列表_Layui数据表格之获取表格中所有的数据方法
  3. 个人项目耗时对比记录表
  4. 去除dataframe中的空行_Word中这些一键操作实在太强了!折腾半天的工作,一秒就能搞定!...
  5. Python 学习 DAY1
  6. java mongo分组统计_mongodb 分组 topN
  7. 成为JavaGC专家Part I — 深入浅出Java垃圾回收机制
  8. 在Carmaker中建立自己的交通环境
  9. phpstudy安装及简单使用教程
  10. sql2012下载,安装,激活
  11. SYNOPSYS™光学设计软件---设计自由曲面反射系统
  12. EPLAN2.9程序安装及注意事项
  13. Ubuntu 18安装搜狗拼音
  14. 基于ssm与maven,使用easyui--tree生成类似部门管理树形结构图
  15. linux 查看 man 路径配置文件 man.config,linux中的man(zz)
  16. mysql (1205, 'Lock wait timeout exceeded; try restarting transaction')
  17. 项目管理第十三章项目相关方管理
  18. win7删除系统自带中文简体输入法中美式键盘
  19. mongodb 配置文件解读
  20. 智能巡检机器人的“顺风耳、千里眼、金钟罩”

热门文章

  1. Android 9.0 MTK平台 修改热点自动关闭功能(保持热点打开)
  2. HTML#4(Vue3)
  3. 活了20年多了才知道!蜂蜜十大鲜见真相吓掉小命
  4. iOS之NSData和字节学习
  5. Wordpress漏洞,WPScan使用完整攻略
  6. #记录一下:关于三维建图的一些文章讲解 + Delaunay三角剖分的含义
  7. 微信公众号【阿里技术(ali_tech)】历史文章整理
  8. pytorch深度学习案例(二)——航拍街道语义分割
  9. cctalk录屏翻录工具使用教程
  10. (十)pytorch学习笔记---内容为学习资源摘录整合の梯度下降方法--Adadelta(5)