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

嵌入式数据结构笔记三——单向链表下

文章目录

  • 前言
  • 一、查找链表中间节点:
  • 二、查找链表倒数第k个节点:
  • 三、不知道头结点地址删除链表中间节点:
  • 四、链表的倒置:
  • 五、链表的排序:
    • 1.冒泡排序:
    • 2.选择排序:
  • 六、判断链表是否有环:
  • 七、Makefile:
  • 重点


前言

数组要求内存空间必须连续,链表通过指针操作离散的元素,能高效利用内存中的零碎空间。并以“空间换时间”的方式,实现了高效的插入与删除操作。


正文内容:

一、查找链表中间节点:

在这里插入图片描述

  • 快指针每次走2步,慢指针每次都1步
  • 快指针走到末尾,慢指针走到中间
/* 查找链表中间节点 */
linknode *find_midnode(linknode *phead)
{linknode *pslow = NULL;linknode *pfast = NULL;pslow = pfast = phead->pnext;while (pfast != NULL){pfast = pfast->pnext;if (NULL == pfast){break;}pfast = pfast->pnext;if (NULL == pfast){break;}pslow = pslow->pnext;}return pslow;
}

二、查找链表倒数第k个节点:

在这里插入图片描述

  • 快指针先走k步
  • 慢指针和快指针每次走一步
  • 快指针到达末尾,慢指针少走k步,即倒数第k个元素
/* 查找链表倒数第k个节点 */
linknode *find_last_kth_node(linknode *phead, int k)
{linknode *pfast = NULL;linknode *pslow = NULL;pfast = phead->pnext;pslow = phead->pnext;int i = 0;for (i = 0; i < k; i++){if(NULL == pfast){return NULL;}pfast = pfast->pnext;}while (pfast != NULL){pfast = pfast->pnext;pslow = pslow->pnext;}return pslow;
}

三、不知道头结点地址删除链表中间节点:

在这里插入图片描述

  • 将指针指向的下一个节点的值覆盖当前节点的值
  • 删除下一个节点
/* 删除指定节点 */
int delete_linknode(linknode *ptmpnode)
{linknode *pnextnode = NULL;pnextnode = ptmpnode->pnext;ptmpnode->data = pnextnode->data;ptmpnode->pnext = pnextnode->pnext;free(pnextnode);pnextnode = NULL;	//局部变量也可以不赋return 0;
}

四、链表的倒置:

在这里插入图片描述
将链表中的所有元素倒置

  • 将原链表断开
  • 将所有的元素依次使用头插法插入
/* 链表倒置 */
int reverse_linklist(linknode *phead)
{linknode *pinsertnode = NULL;linknode *ptmpnode = NULL;//将链表从头结点处断开ptmpnode = phead->pnext;phead->pnext = NULL;//依次将所有元素使用头插法插入链表中while (ptmpnode != NULL){pinsertnode = ptmpnode;ptmpnode = ptmpnode->pnext;pinsertnode->pnext = phead->pnext;phead->pnext = pinsertnode;//如果写成pinsertnode->pnext = NULL;则在第二次循环时会断掉}return 0;
}

五、链表的排序:

1.冒泡排序:

在这里插入图片描述

  • 采用冒泡排序思想,定义两个指针,相邻两个元素比较
  • 指针循环向后走,直到ptmpnode2为NULL,即等于pend,循环停止
  • pend赋值为tmpnode1的节点地址
  • 下一轮就可以少比1次
  • 循环将所有大的元素找到,剩余一个小的元素即可
/* 链表的冒泡排序 */
int bubble_sort_linklist(linknode *phead)
{linknode *ptmpnode1 = NULL;linknode *ptmpnode2 = NULL;linknode *pend = NULL;datatype tmpdata;if (NULL == phead->pnext || NULL == phead->pnext->pnext ){return 0;}while (1){ptmpnode1 = phead->pnext;ptmpnode2 = phead->pnext->pnext;if (pend == ptmpnode2)	//如果ptmpnode2和pend的起始位置一致就无须再比了{break;}while (ptmpnode2 != pend){if (ptmpnode1->data > ptmpnode2->data){tmpdata = ptmpnode1->data;ptmpnode1->data = ptmpnode2->data;ptmpnode2->data = tmpdata;}ptmpnode1 = ptmpnode1->pnext;ptmpnode2 = ptmpnode2->pnext;}pend = ptmpnode1;}return 0;
}

2.选择排序:

在这里插入图片描述

  • pswapnode指向要交换的节点
  • pminnode假设的最小值
  • ptmpnode和后续节点比较
/* 链表的选择排序 */
int select_sort_linklist(linknode *phead)
{linknode *pswapnode = NULL;linknode *ptmpnode = NULL;linknode *pminnode = NULL;datatype tmpdata;if (NULL == phead->pnext || NULL == phead->pnext->pnext){return 0;}pswapnode = phead->pnext;while (pswapnode->pnext != NULL){pminnode = pswapnode;ptmpnode = pswapnode->pnext;while (ptmpnode != NULL){if (ptmpnode->data < pminnode->data){pminnode = ptmpnode;}ptmpnode = ptmpnode->pnext;}if (pswapnode != pminnode){tmpdata = pswapnode->data;pswapnode->data = pminnode->data;pminnode->data = tmpdata;}pswapnode = pswapnode->pnext;}return 0;
}

六、判断链表是否有环:

在这里插入图片描述

  • 链表是否有环:
    • 定义两个指针:快指针(每次走2步)和慢指针(每次走1步)
    • 快指针 - 慢指针 == 环长 即相遇,快指针和慢指针相等即为链表有环
  • 计算环长:
    • 定义一个指针从环相遇点开始走一圈,直到走到该节点为止
    • 每走一个节点计数,最终可得到环长
  • 获得环的入口位置:
    • 需要公式推导:
      x:起始点到环入口的距离
      y:环入口到相遇点的距离
      z:相遇点到环入口的距离
      pslow:x + y
      pfast: x + y + n (y + z)
      2 * (x + y) = x + y + n (y + z)
      x + y = n (y + z)
      x = n (y + z) - y
      x= (n - 1) (y + z) + z——>当 n = 1 时 x = z
    • 定义一个指针从相遇点开始每次走一步,定义一个指针从开头每次走一步
    • 两个指针相遇的位置即为环入口位置
/* 1.判断链表是否有环2.计算环长3.找到环的入口位置
*/
int circle_linklist(linknode *phead, int *pis_circle, int *pcirlen, linknode
**ppnode)
{linknode *pfast = NULL;linknode *pslow = NULL;linknode *ptmpnode = NULL;linknode *pstartnode = NULL;/* 判断是否有环 */pfast = phead->pnext;pslow = phead->pnext;while (1){pfast = pfast->pnext;if (NULL == pfast){break;}pfast = pfast->pnext;if (NULL == pfast){break;}pslow = pslow->pnext;if (pfast == pslow){break;}}if (NULL == pfast){*pis_circle = 0;return 0;}else{*pis_circle = 1;}/* 统计环长 */int cnt = 1;ptmpnode = pslow->pnext;while (ptmpnode != pslow){cnt++;ptmpnode = ptmpnode->pnext;}*pcirlen = cnt;/* 找到环入口 */pstartnode = phead->pnext;ptmpnode = pslow;while (pstartnode != ptmpnode){pstartnode = pstartnode->pnext;ptmpnode = ptmpnode->pnext;}*ppnode = ptmpnode;return 0;
}

七、Makefile:

a.out:linklist.c main.c gcc linklist.c main.c -g.PHONY:
memcheck://执行 make memcheck 时,会运行 valgrindvalgrind --tool=memcheck --leak-check=full ./a.out
clean://执行 make clean 时,会删除 a.out 文件rm a.out

重点

  • 查找链表倒数第k个节点
  • 链表的倒置
  • 冒泡排序
  • 环形链表

文章转载自:

http://90b3JCv6.xbhpm.cn
http://kiQcwy0t.xbhpm.cn
http://vKQK6Czv.xbhpm.cn
http://n1q6WH5L.xbhpm.cn
http://wWW1dTyi.xbhpm.cn
http://fN6vs9Jo.xbhpm.cn
http://ocTWHY9U.xbhpm.cn
http://rD1KOimx.xbhpm.cn
http://GnKiboDH.xbhpm.cn
http://45gukOkG.xbhpm.cn
http://Y5vB6mxD.xbhpm.cn
http://tdeNE9q1.xbhpm.cn
http://aRL0g7LR.xbhpm.cn
http://eOpSG8WY.xbhpm.cn
http://YSKhzKZv.xbhpm.cn
http://w3aQ9Dgc.xbhpm.cn
http://3ZaAyt8U.xbhpm.cn
http://U6GBaSVV.xbhpm.cn
http://0zs0aiPC.xbhpm.cn
http://oNRCMUzk.xbhpm.cn
http://FBDDBS8w.xbhpm.cn
http://JbXVevvf.xbhpm.cn
http://VZAAjfJW.xbhpm.cn
http://vH6qiZhT.xbhpm.cn
http://IJ8cOTin.xbhpm.cn
http://Y8jLNOZ5.xbhpm.cn
http://CxAEfRkc.xbhpm.cn
http://RhfgDSU3.xbhpm.cn
http://Je6nmM9H.xbhpm.cn
http://xHt5tUiu.xbhpm.cn
http://www.dtcms.com/a/380163.html

相关文章:

  • Proxmox VE远程管理虚拟化隐形入口用cpolar实现
  • discuz所有下载版本和升级工具
  • # AI(学习笔记第八课) 使用langchain的embedding models
  • 2025年渗透测试面试题总结-67(题目+回答)
  • 城市二次供水物联网监测管控管理平台御控解决方案:构建全链路智能水务新生态
  • Python Yolo8 物体识别
  • 一款VS Code连接和管理PostgreSQL的扩展插件,支持AI智能辅助和代理模式
  • 数据结构 Part 2
  • 华为云 GaussDB:金融级高可用数据库,为核心业务保驾护航
  • springcloud二-Sentinel2
  • VSCode中的下载VSIX是指什么?
  • VSCode 远程开发连接(glibc<2.28)
  • 公网IP采用自签名证书配置https并消除浏览器不安全告警
  • VSCode创建Python项目和运行py文件
  • 时钟驱动器原理
  • 【Docker】镜像
  • 换源rocklinux和centos
  • FPGA采集AD7606转Aurora 64B66B传输,基于GTY高速收发器,提供工程源码和技术支持
  • 在VSCode中使用Vim模式
  • 告别单次对话:上下文工程如何重塑AI应用架构
  • 字节 Trae vs 腾讯 CodeBuddy vs 阿里 Qoder:三大 AI-IDE 集成 OneCode 深度对比与体验测评
  • 2025软件测试面试大全(含文档)
  • 第6.1节 精准测试Agent简介
  • I.MX6ULL按键实现(轮询及中断)及工程优化
  • 《用 Scikit-learn 构建 SVM 分类模型:从原理到实战的全流程解析》
  • PostgreSQL 的核心优势数据库优化与面试问题解析
  • 基于支持向量机的空间数据挖掘方法及其在旅游地理经济分析中的应用
  • Python 轻松实现替换或修改 PDF 文字
  • Docker命令大全:从基础到高级实战指南
  • 关于数据采集与处理心得(一)