单链表的查找与长度计算

news2024/11/15 9:29:05


注:本文只探讨"带头结点"的情况(查找思路类似循环找到第i-1 个结点的代码)

一.按位查找:

1.代码演示:

版本一:
#include<stdio.h>
#include<stdlib.h> 
​
​
//定义单链表结点类型
typedef struct LNode  
{
    int data; //每个结点存放一个数据元素
    struct LNode *next; //指针指向下一个结点      
}LNode,*LinkList;
​
​
//初始化一个单链表(带头结点)
bool InitList(LinkList &L)
{
    L = (LNode *)malloc( sizeof(LNode) ); //分配一个头结点
    if(L==NULL) //代表内存不足,分配失败-->意味着带头结点的单链表无法创建 
    {
        return false;
    }
    else
    {
        L -> next = NULL; //头结点之后暂时还没有节点,所以指向NULL
        return true; 
    } 
} 
​
​
//判断单链表是否为空(带头结点)
bool Empty(LinkList L)
{
    if(L->next==NULL) //头结点之后如果指向NULL,代表没有数据 
    {
        return true;
    }
    else
    {
        return false;
    }
} 
​
​
//按位查找,返回第i个元素(带头结点即第0个结点)
LNode * GetElem(LinkList L,int i)
{
    if(i<0)
    {
        return NULL;
    }
    LNode *p; //指针p指向当前扫描到的结点 
    int j=0; //当前p指向的是第几个结点:j为0代表头结点 
    p=L; //L指向头结点,头结点是第0个结点(不存数据)
    while(p!=NULL && j<i) //循环找到第i个结点 
    {
        p = p->next;
        j++;
    }  
    return p; 
} 
 
​
int main()
{
    //声明一个指向单链表的指针
    LinkList L;
    //初始化一个空表
    InitList(L); 
    return 0;
} 
版本二:王道书版本
#include<stdio.h>
#include<stdlib.h> 
​
​
//定义单链表结点类型
typedef struct LNode  
{
    int data; //每个结点存放一个数据元素
    struct LNode *next; //指针指向下一个结点      
}LNode,*LinkList;
​
​
//初始化一个单链表(带头结点)
bool InitList(LinkList &L)
{
    L = (LNode *)malloc( sizeof(LNode) ); //分配一个头结点
    if(L==NULL) //代表内存不足,分配失败-->意味着带头结点的单链表无法创建 
    {
        return false;
    }
    else
    {
        L -> next = NULL; //头结点之后暂时还没有节点,所以指向NULL
        return true; 
    } 
} 
​
​
//判断单链表是否为空(带头结点)
bool Empty(LinkList L)
{
    if(L->next==NULL) //头结点之后如果指向NULL,代表没有数据 
    {
        return true;
    }
    else
    {
        return false;
    }
} 
​
​
//按位查找,返回第i个元素(带头结点即第0个结点)
LNode * GetElem(LinkList L,int i)
{
    int j=1; //代表p结点刚开始指向第一个结点(不是头结点) 
    LNode *p=L->next;
    if(i==0)
    {
        return L; //返回头结点 
    }
    if(i<1)
    {
        return NULL;
    }
    while(p!=NULL && j<i) //循环找到第i个结点 
    {
        p = p->next;
        j++;
    }  
    return p; 
} 
 
​
int main()
{
    //声明一个指向单链表的指针
    LinkList L;
    //初始化一个空表
    InitList(L); 
    return 0;
} 

2.返回第0个元素即头结点:

3.返回的结点大于链表的长度:

while循环进行到第5次时p指向NULL,不满足下一次循环条件,跳出while循环,此时返回的p为NULL:代表查找失败

最终可知当i值不合法时即i为负数或者i值大于链表长度时最终都返回NULL,因此只需要判断返回结果是否为NULL即可

得知是否查找成功。

4.返回的结点在链表内:

a.计算时间复杂度需要要查找的元素在合法范围内。

b.平均时间复杂度是指此次输入的i值它取的合法范围内的任何一个数字的概率都等可能的情况,

具体的算法和顺序表的按位查找的分析方法一样。

5.封装:

案例一:GetElem用来获取第i个结点,传入参数i-1即可找到第i-1个结点

案例二:后插操作的加入

右下角的InsertNextNode函数中需要一个if(p==NULL)进行是否为空指针的判断,因为如果传入GetElem函数的i值不合法即i-1也不合法,会导致p为NULL即空指针:


二.按值查找:

1.代码演示:

按值查找操作只能从第一个结点开始循环依次向后查找:

#include<stdio.h>
#include<stdlib.h> 
​
​
//定义单链表结点类型
typedef struct LNode  
{
    int data; //每个结点存放一个数据元素
    struct LNode *next; //指针指向下一个结点      
}LNode,*LinkList;
​
​
//初始化一个单链表(带头结点)
bool InitList(LinkList &L)
{
    L = (LNode *)malloc( sizeof(LNode) ); //分配一个头结点
    if(L==NULL) //代表内存不足,分配失败-->意味着带头结点的单链表无法创建 
    {
        return false;
    }
    else
    {
        L -> next = NULL; //头结点之后暂时还没有节点,所以指向NULL
        return true; 
    } 
} 
​
​
//判断单链表是否为空(带头结点)
bool Empty(LinkList L)
{
    if(L->next==NULL) //头结点之后如果指向NULL,代表没有数据 
    {
        return true;
    }
    else
    {
        return false;
    }
} 
​
​
//按值查找,找到数据域等于e的结点
LNode * LocateElem(LinkList L,int e)
{
    LNode *p= L->next; //L代表头结点,L->next就是第一个节点,此时p就是第一个结点 
    //从第一个结点开始查找数据域为e的结点(头结点不存数据,所以不从头结点开始)
    while(p != NULL && p->data != e)
    {
        p = p->next;
    }
    //找到后返回该节点指针,否则返回NULL
    return p; 
} 
 
​
int main()
{
    //声明一个指向单链表的指针
    LinkList L;
    //初始化一个空表
    InitList(L); 
    return 0;
} 

平均时间复杂度为O(n)。

2.图解:

例一:

p为第一个节点,第一次循环时p不为NULL且p内部的值不为8,符合循环条件,指向p = p->next即向后指一个元素:

第二次循环时p内部的值为8,不符合循环条件,跳出while循环:

例二:

最终返回NULL,代表不存在数据域为6的结点。

3.如果要找的数据域元素不是基本数据类型如结构体类型,就需要复杂的判断:

如结构体(struct)类型要用到运算符"."访问每一个成员变量来比较。


三.求单链表的长度:


四.总结:


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

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

相关文章

C语言 | Leetcode C语言题解之第401题二进制手表

题目&#xff1a; 题解&#xff1a; char** readBinaryWatch(int turnedOn, int* returnSize) {char** ans malloc(sizeof(char*) * 12 * 60);*returnSize 0;for (int i 0; i < 1024; i) {int h i >> 6, m i & 63; // 用位运算取出高 4 位和低 6 位if (h &…

针对网上nbcio-boot代码审计的actuator方法的未授权访问漏洞和ScriptEngine的注入漏洞的补救

针对网上下面文章的漏洞补救 奇安信攻防社区-代码审计之nbcio-boot从信息泄露到Getshell 一、未授权分析 在ShiroConfig中放开了actuator方法的未授权访问 org/jeecg/config/shiro/ShiroConfig.java:156 上面问题,先注释掉上面的未授权访问,实际就是代码注释掉 二、、RCE…

秒懂Linux之管道通信

目录 前言 进程间通信目的 管道通信 原理 匿名管道 测试样例 情况与特点 模拟进程池 命名管道 全部代码 前言 两个进程之间可以进行数据的直接传递吗&#xff1f;——不可以&#xff0c;进程必须得具备独立性。 进程间通信目的 数据传输&#xff1a;一个进程需要将…

odoo14 | 报错:Database backup error: Access Denied

这两天抽空想为自己快速做一个简单的管理系统&#xff0c;来信息化管理一下自己家里的一些菜谱、电视剧下载清单等事情&#xff0c;我又不想大动干戈的用Java写管理系统&#xff0c;我就想用已经手生了两年半的odoo快速搭一个系统用用得了&#xff0c;结果还遇上了这么个事 根…

Java设计模式—面向对象设计原则(四) ----->接口隔离原则ISP (完整详解,附有代码+案例)

文章目录 3.4 接口隔离原则(ISP)3.4.1 概述3.4.2 案列 3.4 接口隔离原则(ISP) Interface Segregation Principle&#xff0c;简称ISP 3.4.1 概述 客户端测试类不应该被迫依赖于它不使用的方法&#xff1b;一个类对另一个类的依赖应该建立在最小的接口上。 3.4.2 案列 面看…

PMP--一模--解题--21-30

文章目录 9.资源管理21、 [单选] 项目经理发现一个不可预料的高影响风险已经成为项目的一个因素&#xff0c;团队成员之间的自身利益导致问题得不到解决&#xff0c;项目经理必须快速行动&#xff0c;让团队重新集中精力&#xff0c;以便项目恢复进度&#xff0c;项目经理应该使…

通信工程学习:什么是LCAS链路容量调整机制

LCAS&#xff1a;链路容量调整机制 LCAS&#xff08;Link Capacity Adjustment Scheme&#xff09;链路容量调整机制是一种在ITU-T G.7042中定义的技术&#xff0c;旨在解决传统SDH&#xff08;同步数字体系&#xff09;网络在传输数据业务时带宽分配不灵活的问题。以下是LCAS链…

【 C++ 】C/C++内存管理

前言&#xff1a; &#x1f618;我的主页&#xff1a;OMGmyhair-CSDN博客 目录 一、C/C内存分布 二、C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free malloc&#xff1a; calloc&#xff1a; realloc&#xff1a; free&#xff1a; 三、C内存管理方式…

用Mapmost聚类图分析世界

聚类地图是一种数据可视化工具&#xff0c;能够帮助用户在地图上直观地显示大量地理数据点。当数据点过多时&#xff0c;单独显示每个点会使地图变得混乱&#xff0c;而聚类地图通过将相近的数据点聚集在一起&#xff0c;减少了视觉复杂性&#xff0c;便于分析和理解。聚类地图…

在Linux上安装中创中间件InforSuiteAS(二进制文件安装)

在Linux上安装中创中间件InforSuiteAS&#xff08;二进制文件安装&#xff09; 前言1、环境准备1.1 支持的操作系统1.2 依赖软件 2、安装步骤2.1 下载并解压安装包2.2 执行安装2.3 修改防火墙设置2.4 启动InforSuiteAS2.5 InforSuiteAS常用命令2.6 验证安装 3、常见问题及解决方…

【Petri网导论学习笔记】Petri网导论入门学习(三)

Petri网导论入门学习&#xff08;三&#xff09; Petri 网导论学习笔记&#xff08;三&#xff09;定义 1.4定义 1.5定义 1.6定义 1.7 Petri 网导论学习笔记&#xff08;三&#xff09; 如需学习转载请注明原作者并附本帖链接&#xff01;&#xff01;&#xff01; 如需学习转载…

Axure设计之全屏与退出全屏交互实现

在Axure RP中&#xff0c;设计全屏与退出全屏的交互功能可以极大地提升用户体验&#xff0c;尤其是在展示产品原型或进行演示时。本文将详细介绍如何在Axure RP中通过结合JavaScript代码实现全屏与退出全屏的交互效果。 ​ Axure原型设计web端交互元件库&#xff1a;https://…

网络安全产品认证证书大全(持续更新...)

文章目录 一、引言二、《计算机信息系统安全专用产品销售许可证》2.1 背景2.2 法律法规依据2.3 检测机构2.4 检测依据2.5 认证流程2.6 证书样本 三、《网络关键设备和网络安全专用产品安全认证证书》3.1 背景3.2 法律法规依据3.3 检测机构3.4安全认证和安全检测依据标准3.5 认证…

9月→2024年计算机与信息安全国际会议

【9月→郑州、吉隆坡双会场】 Springer-LNICST &#x1f525;&#x1f525;2024年计算机与信息安全国际会议&#xff08;WCCIS 2024&#xff09; 会议时间&#xff1a;2024年9月20-22日 论文收录&#xff1a;EI&#xff0c;Scopus稳定检索 网络安全&#xff0c;访问控制&am…

了解MySQL 高可用架构:主从备份

为了防止数据库的突然挂机&#xff0c;我们需要对数据库进行高可用架构。主从备份是常见的场景&#xff0c;通常情况下都是“一主一从/(多从)”。正常情况下&#xff0c;都是主机进行工作&#xff0c;从机进行备份主机数据&#xff0c;如果主机某天突然意外宕机&#xff0c;从机…

Android 13 固定systemUI的状态栏为黑底白字,不能被系统应用或者三方应用修改

目录 一.背景 二.思路 三.代码流程 1.colos.xml自定义颜色 2.设置状态栏的背景颜色 3.对View进行操作 ①.对Clock(状态栏左侧的数字时钟)进行操作 ②.对电池(BatteryMeterView)进行操作 4.锁屏状态栏 5.patch汇总 一.背景 客户需求将状态栏固定成黑底白字,并且不能让系…

红外小目标检测:基于深度学习

目录 ​编辑 1.红外成像技术的优势 2.红外小目标检测的基本原理 常用方法 1. 背景抑制法 2. 基于滤波的方法 3. 基于模型的方法 4. 基于深度学习的方法 5. 多传感器融合方法 3.代码实战 案例背景 数据准备 模型选择 代码实现 讲解 4.应用场景 5.未来发展趋势 …

NISP 一级 | 4.2 操作系统的安全威胁

关注这个证书的其他相关笔记&#xff1a;NISP 一级 —— 考证笔记合集-CSDN博客 0x01&#xff1a;漏洞和漏洞扫描 对计算机系统安全威胁最大的就是系统本身的漏洞&#xff0c;只有存在漏洞&#xff0c;黑客才有机会入侵我们的计算机系统。具统计证明&#xff0c;99% 的黑客攻击…

基于spring实现博客项目的删除和更新(五)

8. 实现用户退出 前端直接清除掉token即可. 实现客⼾端代码 <注销>链接已经提前添加了onclick事件 &#xff0c;在common.js中完善logout⽅法 function logout(){localStorage.removeItem("user_token");location.href "blog_login.html"; } 点击…

Adobe 将推出人工智能视频模型 Firefly 视频模型: 最长 5 秒,支持视频编辑

最近&#xff0c;Adobe 发布了一款全新的创意工具–Adobe Firefly 视频模型。 这一创新工具标志着 Adobe 在现有 Firefly 生成式人工智能图像模型的基础上&#xff0c;大胆涉足人工智能生成视频领域。 Adobe 表示&#xff0c;该模型是经过道德训练的&#xff0c;使用的数据都是…