算法库应用-有序单链表插入节点

学习源头:

模仿贺利坚老师单链表排序文章浏览阅读5.9k次。  本文针对数据结构基础系列网络课程(2):线性表中第11课时单链表应用举例。例:拆分单链表 (linklist.h是单链表“算法库”中的头文件,详情单击链接…)//本程序严格讲有个bug,详见1楼#include <stdio.h>#include <malloc.h>#include "linklist.h"void split(LinkList *..._单链表生活例子https://blog.csdn.net/sxhelijian/article/details/48377185

构建单链表插入节点, 并保持有序单链表构造

本人解析博客:有序单链表插入节点文章浏览阅读1.3k次,点赞8次,收藏11次。跳出遍历的时候 , pre->next->data 大于等于新节点 ,那么 pre 指向的就是区间的左端点,pre->next指向的就是区间的右端点 ,按照上面的插入方法插入就可以了。当 pre 指向的节点的下一个节点比 新节点数值大 , 就跳出遍历,并且还要有下一个节点,没有的话,我们直接把新节点插入到尾结点就可以了。所以我们首先要找到这个区间, 然后 让 左端点的节点的后继指针指向 e , e的后继指针指向右端点就可以了。所以主要的问题是找到这个区间 ,然后让pre 指向区间的左端点 就行了。_实现单链表的有序插入。在一组有序的数中,从键盘输入一个元素值key,保证这组数仍https://blog.csdn.net/qq_57484399/article/details/127171275

更新版本日志:

V1.0 : 模仿老师,并构建增加 bool LinkList_sorting(LinkList *&L); 算法函数库,

基础上, 进行遍历对比,  插入节点, 保持有序构造

目录

更新版本日志:

V1.0:

功能函数 : ListInsert_orderly

使用构建函数库:

singlelist.h

singlelist.cpp

测试main.cpp

运行结果:

V1.0:

功能函数 : ListInsert_orderly

/**************************************************
函数名: ListInsert_orderly
功  能: 在一个有序链表的基础上,进行插入, 从而还是有序链表
参  数: (1)LinkList *&L:处理过的有序链表(2)ElemType insert_value:插入的元素
注 意:   ① 我们此时插入的是从小到大的有序表, 我们只需找到 最大节点的前一个节点即可② preMaxNode只是遍历节点,刚开始是从小到大,直到遇到 插入节点 < 链表节点,我们把插入节点,放在链表节点前面这个是继续的条件, 结束的条件是preMaxNode->next == NULL || insert_value < preMaxNode->data③不存在空,因为就算只有头结点, 我们直接插入preMaxNode后即可④ 思路理清, preNode_Bigger是为了存储元素位置Bigger_Node是为了方便对比元素值,避免混乱
定义变量含义:(1)LinkList *preNode_Bigger:遍历找到最大节点的前一个节点,用来存储位置(2)LinkList *Bigger_Node:对比插入的最大节点,用来和插入值进行比较(3)LinkList *newNode: 插入构建的新节点(4)int counter:增加调试插入的位置返回值: 无
**************************************************/
void ListInsert_orderly(LinkList *&L, ElemType insert_value)
{LinkList *preNode_Bigger = L;   //①LinkList *Bigger_Node = preNode_Bigger->next;   //④LinkList *newNode;int counter = 0;while(preNode_Bigger->next != NULL && insert_value > Bigger_Node->data )//②{counter++;preNode_Bigger = preNode_Bigger->next;Bigger_Node = preNode_Bigger->next;}printf("\n %d 成功插入单链表,成为第 %d 个元素\n",insert_value,counter+1);//③newNode = (LinkList*)malloc(sizeof(LinkList));newNode->data = insert_value;    //构建新节点newNode->next = Bigger_Node;preNode_Bigger->next = newNode;//插入}

使用构建函数库:

singlelist.h
#ifndef SINGLELIST_H_INCLUDE
#define SINGLELIST_H_INCLUDE#include <stdio.h>
#include <malloc.h>typedef int ElemType;   //定义单链表节点类型typedef struct LNode
{ElemType data;struct LNode *next; //指向后继节点}LinkList;
//①头插法建立单链表
void CreatList_Head(LinkList *&L, ElemType Array_used[], int Array_number);
//②尾插法建立单链表
void CreatList_Tail(LinkList *&L, ElemType Array_used[], int Array_number);
//③输出单链表
void DisplayLinkList(LinkList *L);
//④销毁单链表
void DestroyLinkList(LinkList *&L);
//⑤ 初始化线性表
void InitLinkList(LinkList *&L);
//⑥ 判断线性表是否为空表
bool LinkListEmpty(LinkList *L);
//⑦ 返回单链表L中数据节点的个数
int LinkListLength(LinkList *L);
//⑧ 求线性表L中指定位置的某个数据元素
bool SpecificLocate_Value(LinkList *L,int location, ElemType &value);
//⑨ 按元素值查找特定元素的位置
int SpecificValue_Location(LinkList *L, ElemType value);
//⑩ 把元素插入到特定位置
bool LinkList_InsertElement(LinkList *&L, int location, ElemType &value);
//(11) 删除特定位置的节点元素
bool LinkList_Delete_Location(LinkList *&L,int location, ElemType &value);
//(12)单链表删除其中其最大节点元素
bool  DeleteMaxNode(LinkList *&L);
//(13)对单链表中元素进行排序(至少有2个数据节点)
bool LinkList_sorting(LinkList *&L);
#endif // SINGLELIST_H_INCLUDE
singlelist.cpp
#include "singlelist.h"/**************************************************
①函数名: CreatList_Head
功  能: 头插法建立单链表
参  数: (1)LinkList *&L: 传入的单链表指针地址(2)ElemType Array_used[]:要用来建表的数组(3)int Array_number: 数组的长度
返回值:    无
**************************************************/
void CreatList_Head(LinkList *&L, ElemType Array_used[], int Array_number)
{int counter;LinkList *newnode;L = (LinkList *)malloc(sizeof(LinkList)); //创建头结点L->next = NULL;for(counter = 0; counter < Array_number; counter++){newnode = (LinkList *)malloc(sizeof(LinkList));  //创建新节点newnode->data = Array_used[counter];newnode->next = L->next;         //将newnode插在原开始结点之前,头结点之后L->next = newnode;}
}
/**************************************************
②函数名: CreatList_Tail
功  能: 尾插法建立单链表
参  数: (1)LinkList *&L: 传入的单链表指针地址(2)ElemType Array_used[]:要用来建表的数组(3)int Array_number:数组的长度
返回值:   无
**************************************************/
void CreatList_Tail(LinkList *&L, ElemType Array_used[], int Array_number)
{int counter;LinkList *newnode,*tailnode;L = (LinkList *)malloc(sizeof(LinkList));//创建头结点L->next = NULL;tailnode = L;       //尾结点tailnode始终指向终端结点,开始指向头结点for(counter = 0; counter < Array_number; counter++){newnode = (LinkList *)malloc(sizeof(LinkList)); //创建新节点newnode->data = Array_used[counter];tailnode->next = newnode;   //将新节点插入到尾结点之后tailnode = newnode;         //更新尾结点}tailnode->next = NULL;          //终端结点next域置空
}/**************************************************
③函数名: DisplayLinkList
功  能: 输出单链表
参  数: (1)LinkList *L:将要输出的单链表
返回值: 无
**************************************************/void DisplayLinkList(LinkList *L)
{LinkList *shownode;shownode = L->next;while(shownode != NULL){printf("%d",shownode->data);printf(" ");shownode = shownode->next;        //一直遍历,直到指向尾->newt = NULL}printf("\n");
}
/**************************************************
④函数名: DestroyLinkList
功  能: 销毁单链表
参  数: (1)LinkList *&L:要销毁的单链表
注意:① 等到指引下一个节点的指针为Null时就跳出,避免出现野指针,此时再销毁destroyNode② 避免断开联系,记录 销毁节点的下一个节点③避免空指针异常
返回值: 无
**************************************************/
void DestroyLinkList(LinkList *&L)
{LinkList *destoryNode,*nextNode;destoryNode = L;nextNode = destoryNode->next;while(nextNode != NULL)        //①{free(destoryNode);destoryNode = nextNode;nextNode = destoryNode->next;   //②}free(destoryNode);L->next = NULL;        //③
}
/**************************************************
⑤函数名: InitLinkList
功  能: 初始化单链表
参  数: LinkList *&L:要被初始化的链表指针地址
返回值: 无
**************************************************/
void InitLinkList(LinkList *&L)
{L = (LinkList *)malloc(sizeof(LinkList));//创建头结点L->next = NULL;
}
/**************************************************
⑥函数名: LinkListEmpty
功  能: 判断单链表是否为空
参  数: (1)LinkList *L:要判断的单链表
返回值: bool: 是否为空? treu:false
**************************************************/
bool LinkListEmpty(LinkList *L)
{return (L->next == NULL);
}/**************************************************
⑦函数名: LinkListLength
功  能: 返回单链表L中数据节点的个数
参  数: LinkList *L:要计算的数据节点
返回值: int: 线性表数据节点个数值
**************************************************/
int LinkListLength(LinkList *L)
{int counter = 0;LinkList *nowNode = L;while(nowNode->next != NULL){counter++;nowNode = nowNode->next;}return counter;
}/**************************************************
⑧函数名: GetLocateValue
功  能: 求特定位置的数据元素值
参  数: (1)LinkList *L:要找的单链表(2)int location:所要找的位置(3)ElemType &value: 传递回所要找的值
注意: ① 判断跳出的时候, 是查找成功, 还是抵达末尾② counter == 要找到序号,则跳出,所以counter < location  ,nowNode指向的节点为空,则到末尾,则跳出③④ 这两条语句, 所指向的序号和节点, 是同步的, 位置到或者此节点为空,则跳出
返回值: bool: 是否查找成功? true:false
**************************************************/
bool SpecificLocate_Value(LinkList *L,int location, ElemType &value)
{int counter = 0;LinkList *nowNode = L;while(counter < location && nowNode != NULL)//②{counter++;          //③  当前计数的节点nowNode = nowNode->next;//④当前遍历到的节点}if(nowNode == NULL)                //①{return false;}else{value = nowNode->data;return true;}}/**************************************************
⑨函数名:SpecificValue_Location
功  能: 查找特定数据值的节点,并返回其位置
参  数: (1)LinkList *L: 被查找的单链表(2)ElemType e:
注  意:  ①从头结点后的第一个节点开始找②while循环内的两条语句是同步指向的③当nowNode为空时(到达末尾仍未找到), counter作废④当nowNode不为空时,跳出时, counter表示所指向节点存在,并符合所需
返回值:
**************************************************/
int SpecificValue_Location(LinkList *L, ElemType value)
{int counter = 1;LinkList *nowNode = L->next;    //①while(nowNode != NULL && nowNode->data != value){nowNode = nowNode->next;counter++;                     //②}if(nowNode == NULL)           //③{return 0;}else                    //④{return counter;}}
/**************************************************
⑩函数名: LinkList_InsertElement
功  能: 在单链表特定位置插入节点
参  数: (1)LinkList *&L:要插入的单链表(2)int location:要插入的位置(3) ElemType &value:插入的数据
思路:    先在单链表L中,找到第 i-1个节点(不算头结点),若存在这样的节点,将值为value的节点 插入到其后面
注意:    ① 计数器和 nowNode是同步往后移动(从L->next开始算第一个节点),直到 找到counter = location-1,②此时 nowNode不为空,则此时nowNode指向要插入位置的 前一个节点③ 覆盖指针前, 牢记 nowNode->next里面存放的是后继节点信息,所以要先处理newNode->next = nowNode->next;然后我们才能再把 nowNode->next指向新节点 newNode
返回值: bool: 是否存在第i-1个节点,并插入成功? true : false
**************************************************/
bool LinkList_InsertElement(LinkList *&L, int location, ElemType &value)
{int counter = 0;LinkList *nowNode = L;LinkList *newNode;while((counter < (location-1)) && (nowNode != NULL)) //①{counter++;nowNode = nowNode->next;}if(nowNode == NULL)//②{return false;}else{newNode = (LinkList *)malloc(sizeof(LinkList));newNode->data = value;newNode->next = nowNode->next;//③nowNode->next = newNode;return true;}
}
/**************************************************
(11)函数名: LinkList_Delete_Location
功  能: 删除特定位置的节点元素
参  数: (1)LinkList *&L:被删除的单链表 (2)int location:特定位置(3) ElemType &value:被删除的元素值
思路:    找到第location-1个元素, 存储第locataion个元素值(判断null),然后free链接 location-1 和 location+1
注意:    ① counter和指针节点是同步的,要么找到location-1个节点,要么到末尾② 虽然可能找到location-1个元素,其可能是最后一个元素,从而导致删除失败需要判断一下,deleteNode是否为空,才能得出是否任务成功③ 指针覆盖还是老生常谈,先存储一下deleteNode(方便free),然后指针交替,然后free
返回值:  bool: 是否删除成功? true:false
**************************************************/
bool LinkList_Delete_Location(LinkList *&L,int location, ElemType &value)
{int counter = 0;LinkList *nowNode = L;LinkList *deleteNode;while(counter < (location-1) && nowNode != NULL)   //①{counter++;nowNode = nowNode->next;}if(nowNode == NULL){return false;}else{deleteNode = nowNode->next;if(deleteNode == NULL)    //②{return false;}value = deleteNode->data;nowNode->next = deleteNode->next;  //③free(deleteNode);return true;}
}/**************************************************
(12)函数名: DeleteMaxNode
功  能: 删除单链表中最大的一个节点
参  数: (1)LinkList *&L:要删除节点的单链表
思路: 四个指针, 最大指针,最大指针前一个节点目前遍历的指针,遍历指针的前一个节点, 边比较,边替换,边遍历
注意:①避免只有一个头结点,造成空指针替换异常②③ 顺序不能变,因为③跳出的时候, 会利用到while的非空条件,避免对比的时候, 出现野指针,直到为空时,即可直接跳出,非空则比较替换
返回值:是否删除成功 ? true:false
**************************************************/
bool   DeleteMaxNode(LinkList *&L)
{LinkList *nowNode,*preNode;LinkList *maxNode,*preMaxNode;nowNode = L->next;preNode = L;maxNode = nowNode;preMaxNode = preNode;if(nowNode == NULL) //①{return false;}while(nowNode != NULL) //直到末尾{if(nowNode->data > maxNode->data)   //②{maxNode = nowNode;preMaxNode = preNode;}preNode = nowNode;       //接着走下一个节点nowNode = nowNode->next;   //③}preMaxNode->next = maxNode->next;free(maxNode);return true;
}/**************************************************
(13)函数名:LinkList_sorting
功  能:对单链表中元素进行排序(至少有2个数据节点)
参  数:LinkList *&L:要进行排序的单链表
注意: ① 空表,或者只有一个数据节点,则不需要排序,返回false② 开始节点必须是头结点,因为我们会用到start_compare->next,③ 把数据节点(第二个数据节点及以后)和原始链表(头结点+一个数据节点)④ 在有序表中,一直找到比前一个节点大,比后一个节点小的空挡,所以时刻对比start_compare->next->data, 并且start_compare->next不能为空(为空代表到达末尾,交替空指针)⑤ 顺序不能变, 避免丢失有序表后续信息(指针覆盖的一句话)
详细链接:https://blog.csdn.net/qq_57484399/article/details/127141307
返回值:bool: 是否符合排序标准,并排序成功  ? true: false
**************************************************/
bool LinkList_sorting(LinkList *&L)
{LinkList *compare,*start_compare,*Remaining_node;if(L->next == NULL || L->next->next == NULL)//①保证至少有2个数据节点{return false;}compare = L->next->next;start_compare = L;  //②开始节点必须是头结点Remaining_node = compare->next;L->next->next = NULL; //③把数据节点(第二个数据节点及以后)和原始链表(头结点+一个数据节点)while(compare != NULL){Remaining_node = compare->next;start_compare = L;while((start_compare->next != NULL) && (compare->data > start_compare->next->data)){start_compare = start_compare->next;} //④compare->next = start_compare->next;start_compare->next = compare;     //⑤compare = Remaining_node;}return true;}
测试main.cpp
#include <stdio.h>
#include "singlelist.h"/**************************************************
函数名: ListInsert_orderly
功  能: 在一个有序链表的基础上,进行插入, 从而还是有序链表
参  数: (1)LinkList *&L:处理过的有序链表(2)ElemType insert_value:插入的元素
注 意:   ① 我们此时插入的是从小到大的有序表, 我们只需找到 最大节点的前一个节点即可② preMaxNode只是遍历节点,刚开始是从小到大,直到遇到 插入节点 < 链表节点,我们把插入节点,放在链表节点前面这个是继续的条件, 结束的条件是preMaxNode->next == NULL || insert_value < preMaxNode->data③不存在空,因为就算只有头结点, 我们直接插入preMaxNode后即可④ 思路理清, preNode_Bigger是为了存储元素位置Bigger_Node是为了方便对比元素值,避免混乱
定义变量含义:(1)LinkList *preNode_Bigger:遍历找到最大节点的前一个节点,用来存储位置(2)LinkList *Bigger_Node:对比插入的最大节点,用来和插入值进行比较(3)LinkList *newNode: 插入构建的新节点(4)int counter:增加调试插入的位置返回值: 无
**************************************************/
void ListInsert_orderly(LinkList *&L, ElemType insert_value)
{LinkList *preNode_Bigger = L;   //①LinkList *Bigger_Node = preNode_Bigger->next;   //④LinkList *newNode;int counter = 0;while(preNode_Bigger->next != NULL && insert_value > Bigger_Node->data )//②{counter++;preNode_Bigger = preNode_Bigger->next;Bigger_Node = preNode_Bigger->next;}printf("\n %d 成功插入单链表,成为第 %d 个元素\n",insert_value,counter+1);//③newNode = (LinkList*)malloc(sizeof(LinkList));newNode->data = insert_value;    //构建新节点newNode->next = Bigger_Node;preNode_Bigger->next = newNode;//插入}int main()
{LinkList *A;//定义数组ElemType test_array[] = {9,3,5,7,8,2,1,6};//尾插法建立单链表CreatList_Tail(A,test_array,8);//输出展示DisplayLinkList(A);//把单链表变有序if(LinkList_sorting(A)){printf("排序成功!\n");}//输出展示DisplayLinkList(A);//再在此基础上, 添加元素, 时钟保持有序链表(输出,插入到了第几个位置)ListInsert_orderly(A,4);//输出展示DisplayLinkList(A);//销毁,释放空间DestroyLinkList(A);if(LinkListEmpty(A)){printf("\n成功销毁单链表A\n");}printf("\nA销毁后长度 %d \n",LinkListLength(A));return 0;
}
运行结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/623057.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

每日两题 / 22. 括号生成 54. 螺旋矩阵(LeetCode热题100)

22. 括号生成 - 力扣&#xff08;LeetCode&#xff09; dfs生成合法的括号序列即可 class Solution { public:vector<string> ans;void dfs(int l, int r, int n, string& s){if (s.size() n * 2){ans.push_back(s);return;}if (l){s "(";dfs(l - 1, …

泰迪智能科技受邀参加花都区产教评技能生态链建设政策宣讲培训会

2024年4月8日&#xff0c;由广州市花都区人力资源和社会保障局主办的花都区产教评技能生态链建设政策宣讲培训会在广州市华风高级技工学校顺利举行。广东省人力资源和社会保障厅职业能力建设处鲍彬科长&#xff0c;广州市人力资源和社会保障局职业能力建设处肖飞扬科长&#xf…

【自媒体创作利器】AI白日梦+ChatGPT 三分钟生成爆款短视频

AI白日梦https://brmgo.com/signup?codey5no6idev 引言 随着人工智能&#xff08;AI&#xff09;技术的快速发展&#xff0c;AI在各个领域都展现出了强大的应用潜力。其中&#xff0c;自然语言处理技术的进步使得智能对话系统得以实现&#xff0c;而ChatGPT作为其中的代表之一…

微服务之分布式链路追踪

一、概述 1.1背景 在微服务框架中&#xff0c;一个由客户端发起的请求在后端系统中会经过多个不同的的服务节点调用来协同产生最后的请求结果&#xff0c;每一个前段请求都会形成一条复杂的分布式服务调用链路&#xff0c;链路中的任何一环出现高延时或错误都会引起整个请求最…

10. Spring MVC 程序开发

本文源码位置: Spring-MVC 1. Spring MVC 概要 摘自Spring官方&#xff1a; Spring Web MVC is the original web framework built on the Servlet API and has been included in the Spring Framework from the very beginning. The formal name, “Spring Web MVC,” comes …

K12智慧校园-医务中心

1 系统概述 学生医务就诊登记&#xff0c;所拿药品登记医务报销&#xff0c;做到学校医务也会智能化管理&#xff1b;学生健康检查登记&#xff0c;做到学校校园安全健康成长。 2 总体规划 1&#xff09;药品类别 设置药品类别给学校医务室药品分类&#xff0c;方便药品管理…

Unity AR开发环境搭建

在上一篇文章中&#xff0c;我定义了各种类型的扩展现实 (XR)。 在其中&#xff0c;我将增强现实 (AR) 定义为&#xff1a;增强现实 (AR) 将数字对象置于物理世界中。 通常&#xff0c;该设备将配备某种类型的相机&#xff08;例如智能手机&#xff09;&#xff0c;可以实时提供…

SpringBlade dict-biz/list SQL 注入漏洞复现

0x01 产品简介 SpringBlade 是一个由商业级项目升级优化而来的 SpringCloud 分布式微服务架构、SpringBoot 单体式微服务架构并存的综合型项目。 0x02 漏洞概述 SpringBlade 后台框架 /api/blade-system/dict-biz/list 路径存在SQL注入漏洞,攻击者除了可以利用 SQL 注入漏洞…

基于Springboot+Vue的Java项目-校园周边美食探索及分享平台系统开发实战(附演示视频+源码+LW)

大家好&#xff01;我是程序员一帆&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &am…

企业指标开发流程新主张

作为数据开发人员&#xff0c;你是否在指标开发过程中有过如下苦恼&#xff1a; Q1、 &#xff08;甲方&#xff09;业务人员&#xff1a;你这个指标计算逻辑不对&#xff0c;我们前期不是这么对的。 &#xff08;乙方&#xff09;卑微的你&#xff1a;Fu*k……我有录音。 …

LeetCode 101 对称二叉树

题目描述 对称二叉树 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true示例 2&#xff1a; 输入&#xff1a;root [1,2,2,null,3,null,3] 输出&#xff1a;false提示&#xf…

【介绍下负载均衡原理及算法】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…