【 C 】在单链表中插入一个新节点的尝试(二)
在上篇博文中:【 C 】在单链表中插入一个新节点的尝试(一),我们最后提到了如果向单链表的开头(起始位置)插入一个节点,上篇博文中给出的程序显然完成不了这任务。
这篇博文中,我们将解决这个问题,给出一个在单链表中插入一个新节点的通用程序,就是无论在哪里插入节点都可以。
下面我们来分析这个棘手的问题:
这篇博文中讨论的案例在上篇博文中,也就是在一个顺序链表中插入一个节点。该链表如下:
试图将 3 插入到链表中,如何做到?难点在哪里?
为了在链表的起始位置插入一个节点,函数必须修改根指针。但是,函数不能访问变量root。
一个稍微好点的解决办法就是把一个指向root的指针作为参数传递给函数。然后使用间接访问操作,函数不仅可以获得root(指向链表第1个节点的指针,也就是根指针)的值,也可以向它存储一个新的指针值。这个参数的类型是什么呢?
由于root是一个指向Node的指针,所以参数的类型固然是Node **,也就是一个指向Node的指针的指针。
调用该函数的方式为:
result = sll_insert( &root, 3 );
下面给出程序:
//插入到一个有序的单链表。函数的参数是一个指向链表根指针的指针以及需要插入的新值
#include <stdlib.h>
#include <stdio.h>
#include "sll_node.h" //这个头文件是前面自己创建的#define FALSE 0
#define TRUE 1int sll_insert( Node **rootp, int new_value )
{Node *previous;Node *current;Node *new; //需要插入的新节点//得到指向第一个节点的指针current = *rootp;previous = NULL;//寻找正确的插入位置,方法是顺序访问链表,直到到达其值大于或等于新插入的节点的值while( current != NULL && current->value < new_value ){previous = current; //始终保存当前节点之前的那个节点current = current->link; //当前节点移动到下一个节点}//为新节点分配内存,并把新值存储到新节点中,如果内存分配失败,函数返回FALSEnew = ( Node *)malloc( sizeof( Node ) );if( new == NULL ){return FALSE;}new->value = new_value;//把新节点插入到链表中,并返回TRUEnew->link = current; //新节点的指针指向当前节点if( previous == NULL )*rootp = new;elseprevious->link = new;return TRUE;}
下面对上面的某些语句做出解释:
previous = NULL;
我们需要这条语句,这样我们就可以在以后检查新值是否为链表的第一个节点。
current = *rootp;
这条语句对根指针参数执行间接访问操作,得到的结果是root的值,也就是指向链表第一个节点的指针。
if( previous == NULL )
*rootp = new;
else
previous->link = new;
这条语句被添加到函数的最后。它用于检查新值是否应该被添加到链表的起始位置。如果是,我们使用间接访问修改根指针,使它指向新节点。如果不是,修改前一个节点的指针指向当前节点。
这个函数可以正确完成任务,而且在许多语言中,这是你能够获得的最佳方案。
在C语言中还有一种看似更好的方案来实现单链表的插入,但看了之后我觉得这种方案已经很不错了,如果感兴趣就自己查看《C与指针》,了解相关内容!
【 C 】在单链表中插入一个新节点的尝试(二)相关推荐
- 【 C 】在单链表中插入一个新节点的尝试(一)
根据<C和指针>中讲解链表的知识,记录最终写一个在单链表中插入一个新节点的函数的过程,这个分析过程十分的有趣,准备了两篇博文,用于记录这个过程. 链表是以结构体和指针为基础的,所以结构体和 ...
- 【 C 】在双链表中插入一个新值的简明程序
上两篇博文讲了如何在单链表中插入一个值: [ C ]在单链表中插入一个新节点的尝试(一) [ C ]在单链表中插入一个新节点的尝试(二) 这篇博文讲解如何在双链表中插入一个值. 单链表的替代方案就是双 ...
- 【 C 】简化双链表插入函数(对在双链表中插入一个新值的简明程序的简化)
目录 背景 第一个技巧是语句提炼(statement factoring) 第二个简化技巧 最终简化版本 背景 上篇博文:[ C ]在双链表中插入一个新值的简明程序,讲了一个简明的双链表插入函数,那个 ...
- 数据结构例16.试设计一个算法, 使得在一个有序的单链表中插入一个元素后仍然有序。
/* 16.试设计一个算法, 使得在一个有序的单链表中插入一个元素后仍然有序. */ # include <iostream> # include <stdlib.h> # i ...
- 通过一趟遍历找出长度为n的单链表中值最大的节点.【数据结构】【单链表】
编写一个函数完成如下功能:通过一趟遍历找出长度为n的单链表中值最大的节点. 要求,在主函数中调用上面的函数测试. 提示:还需要定义其他函数,比如初始化链表,构造单链表,输出单链表. 输出结果: 代码展 ...
- 链表相关操作:创建链表、遍历链表、求链表长度、链表中删除一个节点、链表中插入一个节点、反转单链表...
1 #include<iostream> 2 #include<stdlib.h> 3 4 typedef struct node 5 { 6 int data; 7 stru ...
- java数据结构 -链表 -获取有效节点个数,单链表中倒数k个节点
// 1.获取到单链表的节点的个数(如果有头结点,不统计头结点)public static int getLength(HeroNode head){if (head.next == null){re ...
- 链表问题18——向有序的环形单链表中插入新节点
题目 一个环形链表从头节点开始的顺序为不降序的顺序,也就是如1->2->2->2->3->4这样的链表叫做不降序,同时由最后的节点指回头节点.给定这个环形单链表的头节点h ...
- Coding Interview Guide -- 向有序的环形单链表中插入新节点
[题目] 一个环形单链表从头节点head开始不降序,同时由最后的节点指回头节点.给定这样一个环形单链表的头节点head和一个整数num,请生成节点值为num的新节点,并插入到这个环形链表中,保证调整后 ...
最新文章
- python执行提示包找不到的问题
- Solr Cache使用介绍及分析
- Unity FixedUpdate 与 Update 的线程关系实验
- postgresql数据类型
- Maxscript中渲染中文版Vray完成贴图(VrayCompleteMap)的方法
- docker启动失败,报docker dead but pid file exists,处理方式
- Elasticsearch 实例管理在京东的使用场景及演进之路
- vba校对统计不同工作薄(2)
- springboot使用thymeleaf模板引擎时出现org.xml.sax.SAXParseException的原因与解决办法
- UVA11877 The Coco-Cola Store【模拟】
- 【微软力作】虚拟对抗训练:让预训练模型再次强大!
- 一个c语言源程序至少包含,一个C源程序必须包含一个main函数
- vue面试五之vue修饰符中 .lazy 等用法、Vue v2.4中新增的$attrs及$listeners属性的使用、v-once 的使用场景、vue组件里的定时器该如何销毁、vue海量数据优化等
- 一种改版后检查硬件PCB生产资料的方法***-----Gerber对比,检查的方法
- 手机微信如何取消“其他应用打开”的默认方式?
- 乔布斯与Google鲜为人知的故事
- 微信小程序例子——获取用户登录信息
- C++面向对象 - 继承、派生和多态
- 为什么ios比android快,那些说ios比Android快的,进来看看!
- Vue+ElementUI+.netcore前后端分离框架开发项目实战
热门文章
- java杀死自身并重启_java – android服务在应用程序被杀死时自动重启
- java返回json ajax_Spring MVC 中 AJAX请求并返回JSON的示例
- zippo油和zorro油的区别_干式和油侵式变压器的概念和区别
- php 整形 字符串排序,php-通过特定的字符串值进行排序
- win7 mysql读写分离_mysql 主从复制 读写分离配置
- android 系统的切图方式_UI设计切图规范
- oracle 字典_Oracle只读用户通过JAVA应用程序导出其它用户数据最小权限
- mysql实现树状查询_MySQL实现树状所有子节点查询的方法
- 测试linux写文件系统,linux下各主要文件系统的读写性能测试
- DAC8830可以当做电位器来使用吗?