数据结构(二)单链表

一、链表

(一)概念

逻辑结构:线性
存储结构:链式存储,在内存中不连续

分为有头链表和无头链表
同时又细分为单向、循环、双向链表

(二)有头单向链表示意图

以下数据及地址只是为了方便理解设置
在这里插入图片描述

(三)操作

1. 节点的结构体定义:

① 定义:

typedef struct node
{int data; //保存数据struct node* next;  //记录下一节点的地址,注意此时指针类型不能定义为nd_t*
}nd_t;

② 注意点:

  1. 定义结构体成员时,指针的类型此时不能使用nd_t定义。

2. 创建链表

(1) 函数声明

create_list(nd_t **phead,int num);

该函数需要在内存中申请一块nd_t类型大小的空间,并将其地址返回给main函数中用户定义的指针中;
num是用来初始化这块空间中数据域的值。

(2)注意点:
  1. 必须传入二级指针
  2. phead不能为空,即不能传一个NULL作为形参,后面需要对phead取值
  3. 需要检查是否申请内存成功
(3)示意图

在这里插入图片描述

(4)代码实现
//创建节点
create_list(nd_t **phead,int num){if(NULL==phead){printf("传入指针为NULL");}//*phead可以为空,即main函数中的phead可以是一个空指针//但是phead不能为空,即不能传一个NULL作为形参*phead=(nd_t *)malloc(sizeof(nd_t));if(NULL==*phead){printf("申请空间失败!\n");return -1;}//初始化(*phead)->data=num;(*phead)->next=NULL;return 0;
}

3. 清空

(1) 函数声明

int clean_list(nd_t *phead);

(2)注意点:
  1. 必须传入二级指针
  2. 需要判断传入的列表指针是否是空指针
(3)代码实现
int clean_list(nd_t *phead){if(NULL==phead){printf("传入指针为NULL");return -1;}if(NULL==phead->next){printf("表为空\n");return -1;}nd_t *ptemp=NULL;//使用头删清空while(NULL!=phead->next){ptemp=phead->next;phead->next=ptemp->next;free(ptemp);}ptemp=NULL;return 0;
}

4. 销毁

(1) 函数声明

int destory_list(nd_t **phead);

(2)注意点:
  1. 必须传入二级指针
  2. 需要判断传入的列表指针是否是空指针
(3)代码实现
int destory_list(nd_t **phead){if(NULL==phead || NULL==*phead){printf("传入指针为NULL");return -1;}clean_list(*phead);free(*phead);//free参数不能是一个空指针*phead=NULL;return 0;
}

5. 插入(头插、尾插、任意位置插)

(1)头插
① 函数声明

int insert_list_by_head(nd_t *phead,int num);

② 注意点:
  1. 传入一级指针即可
  2. 需要判断传入的列表指针是否是空指针
③ 示意图

在这里插入图片描述

③ 代码实现
int insert_list_by_head(nd_t *phead,int num){if(NULL==phead){printf("传入指针为NULL");return -1;}//创建新节点nd_t *ptemp = NULL;if(create_node(&ptemp,num)<0){printf("内存分配失败\n");return -1;}ptemp->next=phead->next;phead->next=ptemp;return 0;
}
(2)尾插
① 函数声明

int insert_list_by_tail(nd_t *phead,int num);

② 注意点:
③ 代码实现
int insert_list_by_tail(nd_t *phead,int num){if(NULL==phead){printf("传入指针为NULL");return -1;}nd_t *ptemp=phead;//找到尾节点while(NULL!=ptemp->next){ptemp=ptemp->next;}//创建新节点nd_t *pnew = NULL;if(create_node(&pnew,num)<0){printf("内存分配失败\n");return -1;}ptemp->next=pnew;return 0;
}
(3)任意位置插入
① 函数声明

int insert_list_by_pos(nd_t *phead,int pos,int num);

② 注意点:
  1. 必须传入二级指针
  2. 需要判断传入的列表指针是否是空指针
③ 代码实现
int insert_list_by_pos(nd_t *phead,int pos,int num){if(NULL==phead){printf("传入指针为NULL");return -1;}if(0>pos){printf("位置不合理\n");return -1;}nd_t *ptemp=phead;//找到要插入的位置的前一个节点for(int i=0;i<pos;i++){//当ptemp->next为0时,说明不能继续向下遍历了if(NULL==ptemp->next){printf("位置不合理\n");return -1;}ptemp=ptemp->next;}//创建新节点nd_t *pnew = NULL;if(create_node(&pnew,num)<0){printf("内存分配失败\n");return -1;}pnew->next=ptemp->next;ptemp->next=pnew;return 0;
}

6. 删除(头删、尾删、任意位置删)

(1)头删
① 函数声明

int insert_list_by_tail(nd_t *phead,int num);

② 注意点:
③ 代码实现
int delete_list_by_head(nd_t *phead){if(NULL==phead){printf("传入指针为NULL");return -1;}if(NULL==phead->next){printf("表为空\n");return -1;}nd_t *ptemp=phead->next;phead->next=ptemp->next;free(ptemp);ptemp=NULL;return 0;
}
(2)尾删
① 函数声明

int insert_list_by_tail(nd_t *phead,int num);

② 注意点:
③ 代码实现
int delete_list_by_tail(nd_t *phead){if(NULL==phead){printf("传入指针为NULL");return -1;}if(NULL==phead->next){printf("表为空\n");return -1;}//找到尾节点的前一个节点nd_t *ptemp=phead;while(NULL!=ptemp->next->next){ptemp=ptemp->next;}free(ptemp->next);ptemp->next=NULL;return 0;
}
(3)任意位置删除
① 函数声明

int delete_list_by_pos(nd_t *phead,int pos);

② 注意点:
③ 代码实现
int delete_list_by_pos(nd_t *phead,int pos){if(NULL==phead){printf("传入指针为NULL");return -1;}if(0>pos){printf("位置不合理\n");return -1;}nd_t *ptemp=phead;//找到要删除的位置的前一个节点for(int i=0;i<pos;i++){//当ptemp->next为0时,说明此时ptemp位于链表的最后一个节点,但是此时ptemp后的节点是空,不能进行删除操作//所以如果ptemp->next->next为空时,就不能继续往后移动了if(NULL==ptemp->next->next){printf("位置不合理\n");return -1;}ptemp=ptemp->next;}nd_t *pdel=ptemp->next;ptemp->next=pdel->next;free(pdel);pdel=NULL;return 0;
}

7. 修改

(1) 函数声明

int modify_list_by_pos(nd_t *phead,int pos,int num);

(2)注意点:
  1. 必须传入二级指针
  2. 需要判断传入的列表指针是否是空指针
(3)代码实现
int modify_list_by_pos(nd_t *phead,int pos,int num){if(NULL==phead){printf("传入指针为NULL");return -1;}if(0>pos){printf("位置不合理\n");return -1;}nd_t *ptemp=phead;//找到要修改的位置的节点for(int i=0;i<=pos;i++){//当ptemp->next为0时,说明此时ptemp位于链表的最后一个节点,不能继续后移了if(NULL==ptemp->next){printf("位置不合理\n");return -1;}ptemp=ptemp->next;}ptemp->data=num;return 0;
}

8. 查询

(1) 函数声明

int search_list_by_pos(nd_t *phead,int pos,int *num);

(2)注意点:
  1. 必须传入二级指针
  2. 需要判断传入的列表指针是否是空指针
(3)代码实现
int search_list_by_pos(nd_t *phead,int pos,int *num){if(NULL==phead){printf("传入指针为NULL");return -1;}if(0>pos){printf("位置不合理\n");return -1;}nd_t *ptemp=phead;//找到要查找的位置的节点for(int i=0;i<=pos;i++){//当ptemp->next为0时,说明此时ptemp位于链表的最后一个节点,不能继续后移了if(NULL==ptemp->next){printf("位置不合理\n");return -1;}ptemp=ptemp->next;}*num=ptemp->data;return 0;
}

9. 链表合并

(1) 函数声明

int merge_list(nd_t *phead1,nd_t **phead2);

(2)注意点:
  1. 必须传入二级指针
  2. 需要判断传入的列表指针是否是空指针
(3)代码实现
int merge_list(nd_t *phead1,nd_t **phead2){if(NULL==phead1||NULL==phead2||NULL==*phead2){printf("传参为空\n");return -1;}//先找到表1的尾部nd_t *ptemp=phead1;while(NULL!=ptemp->next){ptemp=ptemp->next;}ptemp->next=(*phead2)->next;free(*phead2);*phead2=NULL;return 0;
}

10. 链表排序

(1) 函数声明

int create_node(node_t **list,int *num);

(2)注意点:
  1. 必须传入二级指针
  2. 需要判断传入的列表指针是否是空指针
(3)代码实现

11. 链表翻转

(1) 函数声明

int create_node(node_t **list,int *num);

(2)注意点:
  1. 必须传入二级指针
  2. 需要判断传入的列表指针是否是空指针
(3)代码实现

12. 链表剔重

(1) 函数声明

int create_node(node_t **list,int *num);

(2)注意点:
  1. 必须传入二级指针
  2. 需要判断传入的列表指针是否是空指针
(3)代码实现

13. 打印链表

(1) 函数声明

int print_list(nd_t *phead);

(2)注意点:
  1. 注意对于边界点的判定
(3)代码实现
//打印
int print_list(nd_t *phead){if(NULL==phead){printf("传入指针为NULL");return -1;}nd_t *ptemp=phead->next;while(NULL!=ptemp){printf("%d ",ptemp->data);ptemp=ptemp->next;}putchar(10);return 0;
}

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

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

相关文章

点云文件pcd基础介绍

我们在做高精地图开发或者相关GIS项目开发的的时候&#xff0c;经常会遇到点云这个问题&#xff0c;点云 想到什么 &#xff0c;当然是PCD文件了。这里整体过一遍pcd 文件。 概述 PCD文件格式是PCL库中使用最广泛且独有的数据格式&#xff0c;旨在补充现有文件格式&#xff0…

Colab/PyTorch - 006 Mask RCNN Instance Segmentation

Colab/PyTorch - 006 Mask RCNN Instance Segmentation 1. 源由2. 用 PyTorch 实现 Mask R-CNN2.1 输入输出2.2 预训练模型2.3 模型预测2.4 目标检测流程2.5 推理示例一示例二示例三 3. 推断时间比较(CPU v.s. GPU)4. 总结5. 参考资料 1. 源由 在《Colab/PyTorch - 004 Torchv…

vue2组件的封装+antd

1.vue2表格的封装使用 表格使用 <standard-tables:columns"columns":dataSource"dataSource":loading"loading"bordered:pagination"{ ...pagination, onChange: onPageChange }"><div slot"warnType" slot-scope…

必应bing国内推广开户,全方位必应广告开户流程介绍!

在所有获客渠道中&#xff0c;搜索引擎广告成为企业扩大品牌影响力、精准触达目标客户的关键途径之一。作为全球领先的搜索引擎之一&#xff0c;必应&#xff08;Bing&#xff09;拥有庞大的用户群体和独特的市场优势&#xff0c;是企业不可忽视的营销阵地。云衔科技&#xff0…

Linux驱动---输入子系统

1.概述 1.1 什么叫做输入子系统 简单来说&#xff0c;输入子系统就是统一各种各样的输入设备的系统&#xff1b; 常见的输入设备比如: 键盘、触摸屏、按键、鼠标。 1.2 为什么要引入输入子系统 每个人写驱动代码都有自己的风格和习惯&#xff0c;导致代码会有一定的差异&…

qt面试经验

目录 1.qt底层原理2.connect的第五个参数3.信号槽的原理4.qt的智能指针QPointerQSharedPointerQScopedPointerQWeakPointerQSharedDataPointerQScopedArrayPointer 5.线程6.事件监听全局事件监听某一类控件的事件监听某一个控件的事件Qt的事件循环事件与信号的区别 7.设计模式单…

python工程打包为一个可执行的exe文件

文章目录 背景步骤安装 PyInstaller打包python脚本生成的文件特殊情况 示例 背景 打包一个Python工程为一个可执行的exe文件&#xff0c;效果是&#xff1a;打包完成之后&#xff0c;这个exe文件在没有python环境的电脑也能运行&#xff0c;不需要安装额外的环境 步骤 安装 P…

vscode添加代办相关插件,提高开发效率

这里写目录标题 前言插件添加添加TODO Highlight安装TODO Highlight在项目中自定义需要高亮显示的关键字 TODO Tree安装TODO Tree插件 单行注释快捷键 前言 在前端开发中&#xff0c;我们经常会遇到一些未完成、有问题或需要修复的部分&#xff0c;但又暂时未完成或未确定如何处…

kafka监控配置和告警配置

Kafka的监控配置和告警配置是确保Kafka集群稳定运行的关键部分。以下是一些关于Kafka监控配置和告警配置的建议&#xff1a; 一、Kafka监控配置 集群级别参数监控&#xff1a; log.retention.hours&#xff1a;用于控制消息在日志中保留的时间。监控此参数的值&#xff0c;确…

【MySQL精通之路】AdminAPI-使用

目录 1.使用 1.1 使用场景 1.2 使用模式 官方文档&#xff1a; MySQL :: MySQL Shell 8.0 :: 6.1 Using MySQL AdminAPI 本文介绍MySQL SHELL提供的MySQL AdminAPI&#xff0c;使您能够管理MySQL实例&#xff0c;使用它们创建InnoDB Cluster、InnoDB ClusterSet和InnoDB R…

合约的值类型

基本数据类型&#xff1a;整数、枚举、布尔&#xff08;类似java的数据类型&#xff09;Address、Contract&#xff08;这两种是solidity特有的数据类型&#xff09;Fixed byte array&#xff08;定长字节数组&#xff09; Integer(int/uint) int/uint 以8位字节递增&#xf…

推荐ChatGPT4.0——数学建模

1.建模助手 2. 可直接上传文档分析 3.获取途径 现在商家有活动&#xff0c;仅仅需要19.9&#xff01;&#xff01;&#xff01;&#xff01; 现在有优惠&#xff1a; 推荐人写&#xff1a;love 周卡&#xff0c;半月卡&#xff0c;月卡优惠码是love&#xff0c; 会优惠10元…

一篇讲透排序算法之插入排序and选择排序

1.插入排序 1.1算法思想 先将数组的第一个元素当作有序&#xff0c;让其后一个元素与其比较&#xff0c;如果比第一个元素小则互换位置&#xff0c;之后再将前两个元素当作有序的&#xff0c;让第三个元素与前两个元素倒着依次进行比较&#xff0c;如果第三个元素比第二个元素…

表现层框架设计之表现层设计模式_1.MVC模式

1.MVC模式三个核心模块 MVC是一种目前广泛流行的软件设计模式。近年来&#xff0c;随着Java EE的成熟&#xff0c;MVC成为了Java EE平台上推荐的一种设计模式。MVC强制性地把一个应用的输入、处理、输出流程按照视图、控制、模型的方式进行分离&#xff0c;形成了控制器…

Github上传时报错The file path is empty的解决办法

问题截图 文件夹明明不是空的&#xff0c;却怎么都上传不上去。 解决方案&#xff1a; 打开隐藏文件的开关&#xff0c;删除原作者的.git文件 如图所示&#xff1a; 上传成功&#xff01;

全面掌握深度学习:从基础到前沿

引言&#xff1a;深入探索深度学习的世界 在人工智能&#xff08;AI&#xff09;的广阔领域中&#xff0c;深度学习已经成为最令人瞩目的技术之一。它不仅推动了科技的许多突破性进展&#xff0c;也正在改变我们的工作和生活方式。本博客旨在全面总结深度学习的关键知识点&…

Rust面试宝典第14题:旋转数组

题目 给定一个数组&#xff0c;将数组中的元素向右移动k个位置&#xff0c;其中k是非负数。要求如下&#xff1a; &#xff08;1&#xff09;尽可能想出更多的解决方案&#xff0c;至少有三种不同的方法可以解决这个问题。 &#xff08;2&#xff09;使用时间复杂度为O(n)和空间…

4、设计模式之工厂模式

文章目录 开始之前简单工厂模式工厂方法模式抽象工厂模式总结 开始之前 本章节是一个系列&#xff0c;里面用的的代码实例都是连贯的。在实现某一种设计模式时&#xff0c;为了减少代码篇幅&#xff0c;前面博客出现model类&#xff08;仅限公用的model类&#xff0c;比如comp…

RAW转换和图像编辑工具:Capture One 23 Pro (win/mac)中文专业版

Capture One 23是一款功能强大的桌面版照片编辑软件&#xff0c;由丹麦PHASE ONE飞思数码公司开发。 以下是该软件的一些主要特点&#xff1a; 强大的RAW处理功能&#xff1a;Capture One 23支持多种品牌的相机和镜头&#xff0c;提供了丰富的RAW处理工具&#xff0c;包括曝光、…

安装ollama并部署大模型并测试

Ollama介绍 项目地址&#xff1a;ollama 官网地址&#xff1a; https://ollama.com 模型仓库&#xff1a;https://ollama.com/library API接口&#xff1a;api接口 Ollama 是一个基于 Go 语言开发的简单易用的本地大语言模型运行框架。可以将其类比为 docker&#xff08;同基…