当前位置: 首页 > 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.dtcms.com/a/314866.html

相关文章:

  • Linux Shell:常用命令汇总
  • 邻近标记技术:研究蛋白互作的利器(一)
  • 论文Review LIO Multi-session Voxel-SLAM | 港大MARS出品!体素+平面特征的激光SLAM!经典必读!
  • 简要探讨大型语言模型(LLMs)的发展历史
  • 每天学一个Linux命令(38):vi/vim
  • 决策树(回归树)全解析:原理、实践与应用
  • Excel商业智能分析报表 【销售管理分析仪】
  • 编译 Paddle 遇到 flashattnv3 段错误问题解决
  • PostgreSQL——表的基本操作
  • 前端接入通义千问(各大模型接入方法类似)
  • 【Spring Boot 快速入门】六、配置文件
  • 15个命令上手Linux!
  • 回归分析:从数据类型到预测模型的核心逻辑
  • 8.4 打卡 DAY 33: 第一个神经网络 - MLP的构建与训练
  • 《时间之隙:内存溢出》
  • [自动化Adapt] 数据脱敏 | 文本替换/图像模糊 | 引擎热插拔 | 多队列并行处理
  • 网络资源模板--基于Android Studio 实现的消消乐游戏
  • ffmpeg下载windows教程
  • 高密度客流识别精度↑32%!陌讯多模态融合算法在智慧交通的实战解析
  • 模拟IC设计提高系列8-运算跨导放大器OTA Operational Transconduct Amplifiers
  • Cursor国产平替重磅开源!离线研发AI助手,拒绝云端受制于人
  • 【数据结构初阶】--顺序表(一)
  • BD202402跑步 线性求逆元 素数筛 数学
  • 数分思维13:AB测试
  • 开源网页生态掘金:从Bootstrap二次开发到行业专属组件库的技术变现
  • 复杂场景识别率↑31%!陌讯多模态融合算法在智慧环卫的实战解析
  • 上一篇文章的补充理解
  • 深度学习零基础入门(4)-卷积神经网络架构
  • sqli-libs通关教程(21-30)
  • 文件上传