当前位置: 首页 > news >正文

单向链表练习

        valgrind:gnu 提供的内存探测工具,可以用来检测内存错误和内存泄漏。

        内存泄漏:申请的空间使用完时没有及时释放,造成内存泄露。

        快慢指针法:是一种通过两个指针以不同速度遍历数据结构的算法技巧,常用于解决链表、数组相关问题。快指针移动速度是慢指针的两倍(或其他固定倍数),通过这种差异实现特定功能。

//函数功能:查找链表中的中间节点(快慢指针法)
//参数://-plink:指向链表对象的指针
//返回值://-成功:返回中间节点的指针//-失败:返回NULL
Node_t *intermediateNode(Link_t *plink)
{Node_t *ptmp = plink->phead;if(ptmp == NULL){printf("error\n");return NULL;}//初始化快慢指针Node_t *pfast = ptmp;Node_t *pshow = ptmp;while(pfast != NULL){pfast = pfast->pnext;    //快指针先移动一步if(NULL ==pfast)         //若快指针移动一步后已经到末尾(链表长度为奇数){break;               //直接退出循环,此时慢指针已经指向中间节点}else{pfast = pfast->pnext;         //快指针再移动一步(共移动两步)pshow = pshow->pnext;         //慢指针移动一步}}return pshow;	   //返回中间节点(慢指针最终位置)
}
//函数功能:查找单向链表的倒数第K个节点
//参数://-plink:指向链表对象的指针//-k:要查找的倒数位置Node_t * kNode(Link_t *plink,Data_type_t k)
{/*初始化快慢指针:均指向链表头节点*/Node_t *pfast = plink->phead;Node_t *pshow = plink->phead;int i;/*快指针先移动k个节点*/  for(i = 0;i < k;i++){if(pfast == NULL){return NULL;}pfast = pfast->pnext;}//快慢指针同步移动:直到快指针到达链表末尾(NULL)//此时慢指针与快指针仍保持k个节点的距离,慢指针即指向倒数第k个节点while(pfast!= NULL){pfast = pfast->pnext;   //快指针继续后移1步pshow = pshow->pnext;   //慢指针同步后移1步}return pshow;    返回慢指针(此时指向倒数第k个节点)
}
//函数功能:链表逆序
//参数://-plink:指向链表对象的指针 
void reserve_link(Link_t *plink)
{Node_t *ptmp = plink->phead;plink->phead = NULL;//遍历原链表while(ptmp != NULL){//保护当前要插入的节点Node_t *pinsert = ptmp;//将ptmp指向下一个节点,以便继续处理下一个节点,防止丢失链表后续部分ptmp = ptmp->pnext;/*头插*/pinsert->pnext =plink->phead;plink->phead = pinsert;}
}
//函数功能:对单向链表进行插入排序(升序)
//参数://-plink:指向链表对象的指针
void sort_link(Link_t *plink)
{//检查链表是否无效或为空if (plink == NULL || plink->phead == NULL) {return ;  //若链表为空或链表头指针为空,直接返回,不排序}//初始化相关指针Node_t *ptmp = plink->phead->pnext;  //ptmp指向链表的第二个节点,用于后续操作plink->phead->pnext = NULL;          //将原链表的头节点变成新链表的第一个节点,并断开后续节点//遍历原链表剩余节点并插入到合适的位置while(ptmp != NULL){Node_t *pinsert = ptmp;    //保存当前要插入的节点ptmp = ptmp->pnext;        //ptmp指向下一个节点,以便后续操作//判断当前节点是否插入新链表头部if(plink->phead->data >= pinsert->data){/*头插*/pinsert->pnext = plink->phead;plink->phead = pinsert;}else{Node_t *p = plink->phead;while(p->pnext != NULL && pinsert->data > p->pnext->data){p = p->pnext;     //向后移动指针p,直到找到合适的位置}pinsert->pnext = p->pnext;      p->pnext = pinsert;}}
}

        循环链表:其最后一个节点的指针指向第一个节点,形成一个闭环。

        有环链表:链表中存在至少一个节点的指针指向链表中的某个先前节点,导致链表形成环状结构。与循环链表不同,有环链表的环不一定从首尾节点开始。

        循环链表是一种特殊的有环链表。

        循环链表是有环链表,但有环链表不一定是有环链表。

//函数功能:判断链表是否有环
int is_loop_link(Link_t *plink)
{if(plink == NULL ||plink->phead == NULL){return 0;}Node_t *pfast = plink->phead;Node_t *pshow = plink->phead;while(pfast != NULL && pfast->pnext != NULL){pfast = pfast->pnext->pnext;pshow = pshow->pnext;if(pfast == pshow){return 1;}}return 0;
}
Node_t *Joseph_loop(Link_t *plink)
{if (is_empty_link(plink)){return NULL;}Node_t *ppre = plink->phead;Node_t *pdel = ppre;while (plink->clen > 1){ppre = ppre->pnext;pdel = pdel->pnext->pnext;ppre->pnext = pdel->pnext;free(pdel);plink->clen--;ppre = ppre->pnext;pdel = ppre;}return ppre;
}

 

http://www.lryc.cn/news/610469.html

相关文章:

  • TCP 协议的“无消息边界”(No Message Boundaries)特性
  • Java 的 APT(Annotation Processing Tool)机制详解
  • 区块链 和 一致性哈希的结合
  • SpringBoot+SpringMVC常用注解
  • 可视化图解算法57:字符串的排列
  • 简要探讨大型语言模型(LLMs)的发展历史
  • AI编程助手:终结996的新希望
  • [激光原理与应用-134]:光学器件 - 图解透镜原理和元件
  • 实现三通道转单通道(灰度图)的两种加权方法
  • Pixel 4D 3.4.4.0 | 支持丰富的壁纸资源,高清画质,高度的个性化设置能力,智能推荐功能
  • Coze Loop:开源智能体自动化流程编排平台原理与实践
  • 可重复读(Repeatable Read)能解决幻读吗?
  • 【unitrix】 7.1 二进制位加法(bit_add.rs)
  • Minio部署和客户端使用 - 版本 2025-05-24T17-08-30Z
  • 县级融媒体中心备份与恢复策略(精简版3-2-1架构)
  • Javascript面试题及详细答案150道(046-060)
  • Linux 交换空间管理
  • 15个命令上手Linux!
  • 力扣top100--哈希
  • PandasAI连接LLM对MySQL数据库进行数据分析
  • 【笔记】重学单片机(51)(下)
  • ArcGIS的字段计算器生成随机数
  • 数据库提权
  • 并发编程常用工具类(下):CyclicBarrier 与 Phaser 的协同应用
  • (论文速读)RMT:Retentive+ViT的视觉新骨干
  • Hadoop HDFS 3.3.4 讲解~
  • 嵌入式知识篇---闪存
  • mysql 数据库系统坏了,物理拷贝出数据怎么读取
  • Deepoc 赋能送餐机器人:从机械执行到具身智能的革命性跨越
  • JavaScript 中的流程控制语句详解