C、C++常用数据结构:链表
文章目录
- 基本概念
- 链表的创建
- 链表结点定义
- 链表创建
- 链表遍历
- 链表释放
- 链表查找
- 链表删除
- 链表插入
- 测试用例
基本概念
参考:链表基础知识详解(非常详细简单易懂)-CSDN博客
- 链表是一种线性存储结构,链表在物理存储上是非连续的,数据元素的逻辑顺序通过链表中的指针链接
- 链表由一系列的结点组成,每个节点主要包含两个部分:数据域+指针域
- 数据域存放实际的数据;指针域存放下一个节点的地址(首地址)
- 链表分为单向链表和双向链表:单向链表由一个指针next,存放下一个节点的首地址;双向链表由next和previous,分别存放下一个节点和上一个节点的首地址
- 常见面试题:链表和数组的对比。链表的内存是不连续的,链表通过节点把离散的数据链接成一个表;而数组是通过开辟一段连续的内存来存储数据。数组成员和链表节点的数据类型可以是标准的C类型或者是用户自定义的类型。数组有起始地址和结束地址,链表没有明确的起始地址和结束地址,为了方便操作,可能会人为规定一个根节点(当然这是对于双向链表来说的,单向链表还是有头尾之分的)
以下代码只针对单链表
链表的创建
链表结点定义
// 定义一个链表节点结构体
typedef struct listNode
{int val;struct listNode *next;
} listNode;
链表创建
/*** 创建链表* 用到了二级指针要改变指针指向的值,传入指针要改变指针的指向(指针本身),传入二级指针*/
void listCreate(listNode **p_head, listNode *p_new)
{listNode *p_move = *p_head;if (*p_head == NULL){*p_head = p_new;}else{while (p_move->next != NULL){p_move = p_move->next;}p_move->next = p_new;p_new->next = NULL;}
}
链表遍历
/*** 遍历链表*/
void listPrint(listNode *head)
{if (head == NULL){cout << "list is NULL" << endl;return;}listNode *p = head;while (p != NULL){cout << p->val << " ";p = p->next;}cout << endl;
}
链表释放
/*** 释放链表*/
void listFree(listNode **head)
{listNode *p = *head;while (*head != NULL){p = *head;*head = (*head)->next;free(p);p = NULL; // 防止野指针}cout << "list free" << endl;
}
链表查找
/*** 链表查找*/
void listFind(listNode *head, int val)
{if (head == NULL)return;listNode *p = head;while (p != NULL){if (p->val == val){cout << "I find " << p->val;}p = p->next;}cout << endl;
}
链表删除
/*** 链表删除*/
void listDelete(listNode **head, int val)
{if (*head == NULL){return;}listNode *slow = NULL;listNode *fast = *head;while (fast != NULL){if (fast->val == val){if (fast == *head){*head = (*head)->next;free(fast);cout << "delete done" << endl;fast = *head;}else{slow->next = fast->next;free(fast);cout << "delete done" << endl;fast = slow->next;}}else{slow = fast;fast = fast->next;}}
}
链表插入
/*** 链表插入* 根据val值来判断插入位置(从小到大)*/
void listInsert(listNode **head, listNode *p_new)
{// 如果链表为空,则插入的结点为头结点if (*head == NULL){*head = p_new;p_new->next = NULL;return;}// 定义快慢指针listNode *slow = NULL;listNode *fast = *head;while (p_new->val >= fast->val && fast->next != NULL){slow = fast;fast = fast->next;}if (p_new->val < fast->val) // 如果找到了大于新结点val的结点,则新结点插入该结点左边{if (fast == *head){p_new->next = *head;*head = p_new;}else{p_new->next = slow->next;slow->next = p_new;}}else // 没有找到就插入右边{fast->next = p_new;p_new->next = NULL;}
}
测试用例
#include <iostream>
#include <vector>
#include <cstdio>using namespace std;// 定义一个链表节点结构体
typedef struct listNode
{int val;struct listNode *next;
} listNode;/*** 创建链表* 用到了二级指针要改变指针指向的值,传入指针要改变指针的指向(指针本身),传入二级指针*/
void listCreate(listNode **p_head, listNode *p_new)
{listNode *p_move = *p_head;if (*p_head == NULL){*p_head = p_new;}else{while (p_move->next != NULL){p_move = p_move->next;}p_move->next = p_new;p_new->next = NULL;}
}/*** 遍历链表*/
void listPrint(listNode *head)
{if (head == NULL){cout << "list is NULL" << endl;return;}listNode *p = head;while (p != NULL){cout << p->val << " ";p = p->next;}cout << endl;
}/*** 释放链表*/
void listFree(listNode **head)
{listNode *p = *head;while (*head != NULL){p = *head;*head = (*head)->next;free(p);p = NULL; // 防止野指针}cout << "list free" << endl;
}/*** 链表查找*/
void listFind(listNode *head, int val)
{if (head == NULL)return;listNode *p = head;while (p != NULL){if (p->val == val){cout << "I find " << p->val;}p = p->next;}cout << endl;
}/*** 链表删除*/
void listDelete(listNode **head, int val)
{if (*head == NULL){return;}listNode *slow = NULL;listNode *fast = *head;while (fast != NULL){if (fast->val == val){if (fast == *head){*head = (*head)->next;free(fast);cout << "delete done" << endl;fast = *head;}else{slow->next = fast->next;free(fast);cout << "delete done" << endl;fast = slow->next;}}else{slow = fast;fast = fast->next;}}
}/*** 链表插入* 根据val值来判断插入位置(从小到大)*/
void listInsert(listNode **head, listNode *p_new)
{// 如果链表为空,则插入的结点为头结点if (*head == NULL){*head = p_new;p_new->next = NULL;return;}// 定义快慢指针listNode *slow = NULL;listNode *fast = *head;while (p_new->val >= fast->val && fast->next != NULL){slow = fast;fast = fast->next;}if (p_new->val < fast->val) // 如果找到了大于新结点val的结点,则新结点插入该结点左边{if (fast == *head){p_new->next = *head;*head = p_new;}else{p_new->next = slow->next;slow->next = p_new;}}else // 没有找到就插入右边{fast->next = p_new;p_new->next = NULL;}
}int main(int argc, char const *argv[])
{listNode *head = NULL, *p_new = NULL;int num = 0;for (int i = 0; i < 10; i++){p_new = (listNode *)malloc(sizeof(listNode));p_new->val = i;listCreate(&head, p_new);}listPrint(head);listFind(head, 3);listDelete(&head, 3);listPrint(head);cout << "结点插入测试" << endl;listNode *p_insert = (listNode *)malloc(sizeof(listNode));p_insert->val = 3;listInsert(&head, p_insert);listPrint(head);listFree(&head);return 0;
}
相关文章:
C、C++常用数据结构:链表
文章目录 基本概念链表的创建链表结点定义链表创建 链表遍历链表释放链表查找链表删除链表插入测试用例 基本概念 参考:链表基础知识详解(非常详细简单易懂)-CSDN博客 链表是一种线性存储结构,链表在物理存储上是非连续的…...
【devops】devops-ansible之剧本变量使用
本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》:python零基础入门学习 《python运维脚本》: python运维脚本实践 《shell》:shell学习 《terraform》持续更新中:terraform_Aws学习零基础入门到最佳实战 《k8》从问题中去学习k8s 《docker学习》暂未更…...
《Linux从小白到高手》理论篇:一文概览常用Linux重要配置文件
List item 今天继续宅家,闲来无事接着写。本篇是《Linux从小白到高手》理论篇的最后一篇了。本篇集中介绍所有常用的Linux重要配置文件。 用这个命令可以查看配置文件所在的位置:如上图 locate "*.conf" "*.ini" "*.cfg&quo…...
采购管理流程:掌握最后阶段的关键要点
采购管理流程是企业运作中的核心职能之一,涵盖了获取商品和服务的一系列步骤,旨在以高效率和经济效益的方式进行。深入理解该流程的每个环节极为关键,特别是最后阶段,这可确保所有采购活动的圆满完成以及与供应商维持良好关系。 …...
cherry-markdown开源markdown组件详细使用教程
文章目录 前言开发定位目标调研技术方案前提工作量安排数据库表设计实现步骤1、引入依赖2、实现cherry-markdown的vue组件(修改上传接口路径)3、支持draw.io组件4、支持展示悬浮目录toc前端使用:编辑状态使用cherry-markdown的vue组件前端使用…...
Android SystemUI组件(10)禁用/重启锁屏流程分析
该系列文章总纲链接:专题分纲目录 Android SystemUI组件 本章关键点总结 & 说明: 说明:本章节持续迭代之前章节的思维导图,主要关注左侧上方锁屏分析部分 应用入口处理流程解读 即可。 在 Android 系统中,禁用锁屏…...
【Geeksend邮件营销】外贸邮件中的一些常用语
外贸邮件中的相关术语丰富多样,涉及邮件的开头、正文、结尾以及特定的商务用语。以下是一些常用的外贸邮件术语及其解释: 一、邮件开头用语 1、问候语: Dear [收件人姓名], Trust this email finds you well. How are you? …...
配置静态ip
背景:因业务需要需要将一台服务器从机房搬到实验室,机房是光纤,实验室是网线,需要重新配置下静态ip 确认网络配置文件(网上没找到,不清楚一下方法对不对) 先随便一个网口连接网线,执行 ifconfig -a 找到带“RUNNING”的(lo不是哈)----eno1 到/etc/sysconfig/network…...
[LeetCode] LCR170. 交易逆序对的总数
题目描述: 在股票交易中,如果前一天的股价高于后一天的股价,则可以认为存在一个「交易逆序对」。请设计一个程序,输入一段时间内的股票交易记录 record,返回其中存在的「交易逆序对」总数。 示例 1: 输入:…...
大开眼界,原来指针还能这么玩?
文章目录 第一阶段:基础理解目标:内容:题目:答案解析: 第二阶段:指针与数组目标:内容:题目:答案解析: 第三阶段:指针与字符串目标:内容…...
揭秘选择知识产权管理系统的常见误区,避免踩坑
在当今知识经济时代,知识产权管理对于企业的发展至关重要。为了提高管理效率和效果,许多企业纷纷选择采用知识产权管理系统。然而,在选择过程中,存在着一些容易陷入的误区。 误区一:只关注功能,忽视用户体验…...
计算机组成原理之存储器的分类
1、按存储介质分类: 半导体存储器:使用半导体器件作为存储元件,如TTL和MOS存储器。这类存储器体积小、功耗低、存取时间短,但断电后数据会丢失。 磁表面存储器:使用磁性材料涂覆在金属或塑料基体表面作为存储介质&…...
Linux(不同版本系统包含Ubuntu)下安装mongodb详细教程
一、下载MongoDB 在MongoDB官网下载对应的MongoDB版本,可以点击以下链接快速跳转到下载页面: mongodb官网下载地址 注意选择和自己操作系统一致的platform,可以先查看自己的操作系统 查看操作系统详情 命令: uname -a 如图:操…...
如何扫描HTTP代理:步骤与注意事项
HTTP代理是一个复杂的过程,通常用于寻找可用的代理服务器,以便在网络中实现匿名或加速访问。虽然这个过程可以帮助用户找到适合的代理,但也需要注意合法性和道德问题。本文将介绍如何扫描HTTP代理,并提供一些建议和注意事项。 什…...
【分布式微服务云原生】gRPC与Dubbo:分布式服务通信框架的双雄对决
目录 引言gRPC:Google的高性能RPC框架gRPC通信流程图 Dubbo:阿里巴巴的微服务治理框架Dubbo服务治理流程图 表格:gRPC与Dubbo的比较结论呼吁行动Excel表格:gRPC与Dubbo特性总结 摘要 在构建分布式系统时,选择合适的服务…...
Python | Leetcode Python题解之第450题删除二叉搜索树中的节点
题目: 题解: class Solution:def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:cur, curParent root, Nonewhile cur and cur.val ! key:curParent curcur cur.left if cur.val > key else cur.rightif cur i…...
[Linux]从零开始的网站搭建教程
一、谁适合本次教程 学习Linux已经有一阵子了,相信大家对LInux都有一定的认识。本次教程会教大家如何在Linux中搭建一个自己的网站并且实现内网访问。这里我们会演示在Windows中和在Linux中如何搭建自己的网站。当然,如果你没有Linux的基础,这…...
牛客——xay loves or与 __builtin_popcount的使用
xay loves or 题目描述 登录—专业IT笔试面试备考平台_牛客网 运行思路 题目要求我们计算有多少个正整数 yy 满足条件 x \text{ OR } y sx OR ys。这里的“OR”是指按位或运算。为了理解这个问题,我们需要考虑按位或运算的性质。 对于任意两个位 a_iai 和 b_…...
Docker学习和部署ry项目
文章目录 停止Docker重启设置开机自启执行docker ps命令,如果不报错,说明安装启动成功2.然后查看数据卷结果3.查看数据卷详情结果4.查看/var/lib/docker/volumes/html/_data目录可以看到与nginx的html目录内容一样,结果如下:5.进入…...
Linux中设置cd命令后直接显示当前目录下的所有文件
Linux中cd命令后默认是不显示该目录下的文件的,略微不方便。换个环境经常遇到需要重新设置的情况,网上已有很多发帖了,这里主要汇总下比较简单且常见的bash与csh下的设置方法。 实现的本质就是将"cd" 与 "ls"组合起来&am…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
React19源码系列之 事件插件系统
事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...
GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
