数据结构 ——无头单链表

news2025/1/18 21:16:51

数据结构 ——无头单链表

一、无头单链表的定义与特性
1、单链表简介
单链表是一种常见的基础数据结构,它由一系列节点组成,每个节点包含数据部分和指向下一个节点的指针。无头单链表是单链表的一种变体,其特点是没有明确的头节点,链表的第一个数据节点直接跟在头指针之后。
2、 无头单链表的特点
无头单链表省去了传统单链表头节点的存储空间,这使得在某些情况下可以更高效地使用内存。它直接通过头指针访问第一个数据节点,便于快速迭代整个链表,但同时也意味着在进行某些操作时,如获取链表长度,需要额外的遍历计数步骤。
二、简单操作实现
1、无头单链表示意图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
尾插代码实现

在这里插入图片描述
2、具体代码实现

//nohead.h
#ifndef NOHEAD_H_
#define NOHEAD_H_
#define NAMESIZE 32
struct score_st
{
    int id;
    char name[NAMESIZE];
    int math;
    int chinese;
};
typedef struct noad_st
{
    struct score_st data;
    struct noad_st *next;
}node;
int list_insert(node **,struct score_st *data);
void list_show(node *);
int list_delete(node **);
// int list_find(node *,int);
struct score_st* list_find(node *,int);
void list_destroy(node *);
#endif

//nohead.c
#include<stdio.h>
#include<stdlib.h>
#include "nohead.h"
//首部插入,由于要改变头指针的指向,故需要传二级指针
int list_insert(node **list,struct score_st *data)
{
    node *new;
    new=malloc(sizeof(*new));
    if(new==NULL)   return -1;
    new->data=*data;
    new->next=*list;
    *list=new;
    return 0;
}
void list_show(node *list)
{
    node *cur;
    for(cur=list;cur!=NULL;cur=cur->next)
    {
        printf("%d %s %d %d\n",cur->data.id,cur->data.name,cur->data.math,cur->data.chinese);
    }

}
//考虑到只有一个结点的删除要改变指针的指向,故传二级指针
int list_delete(node **list)
{
    node *cur;
    if(*list==NULL) return -1;
    //cur指向第一个有效结点
    cur=*list;
    //改变头指针指向,使其指向第一个结点的next指针域
    *list=cur->next;
    free(cur);
    return 0;
}
//按值查找
struct score_st* list_find(node *list,int id)
{
    node *cur;
    #if 0
    for(cur=list;cur!=NULL;cur=cur->next)
    {
        if(cur->data.id==id)
        {
            printf("%d %s %d %d\n",cur->data.id,cur->data.name,cur->data.math,cur->data.chinese);
            return 0;
        }
    }
    printf("Can not find!\n");
    return -1;
    #endif
    /*实际工程开发中,只需要返回给用户一个成功找到的数据就行了,
    不需要替用户决定干什么,如打印输出,则返回类型要改为struct score_st *类型的数据*/
     #if 1
    for(cur=list;cur!=NULL;cur=cur->next)
    {
        if(cur->data.id==id)
        {
            return &cur->data;
        }
    }
    return NULL;
    #endif
}
/*销毁操作不用二级指针,因为不需要修改头结点地址,只是要销毁指针指向的内存而已
但最好传二级指针,把指向第一个数据的指针置为NULL比较合适*/
void list_destroy(node *list)
{
    node *cur;
    if(list==NULL) return ;
    for(cur=list;cur!=NULL;cur=list)
    {
        list=cur->next;
        free(cur);
    }
}
//main.c
#include<stdio.h>
#include<stdlib.h>
#include "nohead.h"
/*注意:!!!无头结点的单向链表不需创建,直接插入就行了,不需要像有头节点一样,
还要创建头结点,即直接创建一个指向空的指针即可 node *list=NULL*/
int main()
{
    node *list=NULL;
    struct score_st tmp,*ptr;
    int i=0,ret;
    #if 1
    for(i=0;i<7;i++)
    {
        tmp.id=i;
        snprintf(tmp.name,NAMESIZE,"stu%d",i);//数组名为指针常量,不能直接赋值;
        tmp.math=rand()%100;
        tmp.chinese=rand()%100;
       // list=list_insert(list,&tmp);
        ret=list_insert(&list,&tmp);//二级指针传参,插入失败时可区分错误类型(返回整形)
        if(ret!=0)
          return -1;
    }
    #endif
    list_show(list);
    #if 0
    if((ptr=list_find(list,6))==NULL)
    {
        printf("Can not find!\n");
    }
    else printf("%d %s %d %d\n",ptr->id,ptr->name,ptr->math,ptr->chinese);
    printf("\n");
    if(ret=(list_delete(&list))!=0)
       return -1;
    list_show(list);
    #endif
    list_destroy(list);
    return 0;
}

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

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

相关文章

阿拉丁论文助手:一键点亮学术之路

在学术研究的海洋中&#xff0c;每一位学者都渴望拥有一盏能够照亮前行道路的神灯。阿拉丁论文助手&#xff0c;正是这样一盏神奇的灯&#xff0c;它以其先进的人工智能技术和丰富的学术资源&#xff0c;为学者们的学术写作提供了全方位的支持。 一、阿拉丁论文助手简介 阿拉丁…

大语言模型应用Text2SQL本地部署实践初探

自从两年前OpenAI公司发布ChatGPT后&#xff0c;大模型(Large Language Model&#xff0c;简称LLM)相关技术在国内外可谓百家争鸣&#xff0c;遍地开花&#xff0c;在传统数据挖掘、机器学习和深度学习的基础上&#xff0c;正式宣告进入快速发展的人工智能(Artificial Intellig…

【UE5 C++课程系列笔记】07——使用定时器实现倒计时效果

使用定时器实现如下倒计时效果 效果 步骤 1. 新建一个Actor类&#xff0c;这里命名为“CountDownTimerActor” 2. 在头文件中先定义倒计时时间和更新剩余时间的函数方法 前向声明一个文本渲染组件 3. 在源文件中引入文本渲染组件 创建文本渲染组件并进行一些设置 实现Update…

synchronized的特性

1.互斥 对于synchronized修饰的方法及代码块不同线程想同时进行访问就会互斥。 就比如synchronized修饰代码块时&#xff0c;一个线程进入该代码块就会进行“加锁”。 退出代码块时会进行“解锁”。 当其他线程想要访问被加锁的代码块时&#xff0c;就会阻塞等待。 阻塞等待…

STM32之SDIO通讯接口和SD卡(九)

STM32F407 系列文章 - SDIO-To-SD Card&#xff08;九&#xff09; 目录 前言 一、SDIO接口 二、SD卡 三、实现程序 1.SD卡结构体参数说明 2.头文件定义 3.函数sd_init() 4.函数HAL_SD_MspInit() 5.函数get_sd_card_info() 6.函数get_sd_card_state() 7.函数sd_read…

Vue 提供了Transition,可以帮助你制作基于状态变化的过渡和动画

官方文档&#xff1a;https://cn.vuejs.org/guide/built-ins/transition.html Transition​ Vue 提供了两个内置组件&#xff0c;可以帮助你制作基于状态变化的过渡和动画&#xff1a; <Transition> 会在一个元素或组件进入和离开 DOM 时应用动画。本章节会介绍如何使用…

04 创建一个属于爬虫的主虚拟环境

文章目录 回顾conda常用指令创建一个爬虫虚拟主环境Win R 调出终端查看当前conda的虚拟环境创建 spider_base 的虚拟环境安装完成查看环境是否存在 为 pycharm 配置创建的爬虫主虚拟环境选一个盘符来存储之后学习所写的爬虫文件用 pycharm 打开创建的文件夹pycharm 配置解释器…

鸿蒙UI开发——渐变色效果

1、概 述 ArkTs可以通过颜色渐变接口&#xff0c;设置组件的背景颜色渐变效果&#xff0c;实现在两个或多个指定的颜色之间进行平稳的过渡。 目前提供三种渐变类型&#xff1a;线性渐变、角度渐变、径向渐变。 我们在鸿蒙UI布局实战 —— 个人中心页面开发中&#xff0c;默认…

渗透测试--数据库攻击

这篇文章瘾小生其实想了很久&#xff0c;到底是放在何处&#xff0c;最终还是想着单拎出来总结&#xff0c;因为数据库攻击对我们而言非常重要&#xff0c;而且内容众多。本篇文章将讲述在各位获取数据库权限的情况下&#xff0c;各个数据库会被如何滥用&#xff0c;以及能够滥…

Java——异常机制(上)

1 异常机制本质 (异常在Java里面是对象) (抛出异常&#xff1a;执行一个方法时&#xff0c;如果发生异常&#xff0c;则这个方法生成代表该异常的一个对象&#xff0c;停止当前执行路径&#xff0c;并把异常对象提交给JRE) 工作中&#xff0c;程序遇到的情况不可能完美。比如…

Idea Spring Initializr没有 Java 8选项解决办法

问题描述 在使用IDEA中的Spring Initializr创建新项目时&#xff0c;Java 版本近可选择Java17,21 。不能选择Java8;SpringBoot 版本也只有 3.x 问题原因 Spring 官方&#xff08; https://start.spring.io/&#xff09;不再提供旧版本的初始化配置 解决方案 方案 1 使用阿里…

npm发布插件到私有仓库保姆级教程

在开发项目的过程中&#xff0c;我们经常需要安装插件依赖&#xff0c;那么怎么把自己开发的组件封装成一个插件&#xff0c;并发布到npm 插件市场或者上传到私有仓库里面呢&#xff1f;今天总结下自己发布插件到私有仓库的记录&#xff1a; 一、创建组件 执行命令创建一个空…

渗透测试---burpsuite(5)web网页端抓包与APP渗透测试

声明&#xff1a;学习素材来自b站up【泷羽Sec】&#xff0c;侵删&#xff0c;若阅读过程中有相关方面的不足&#xff0c;还请指正&#xff0c;本文只做相关技术分享,切莫从事违法等相关行为&#xff0c;本人与泷羽sec团队一律不承担一切后果 视频地址&#xff1a;泷羽---bp&…

关闭windows11的“热门搜索”

win10搜索栏热门搜索怎么关闭&#xff1f;win10搜索栏热门搜索关闭方法分享_搜索_onecdll-GitCode 开源社区 注册表地址是&#xff1a;计算机\HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\ 最后效果如下&#xff1a;

【MySQL】视图详解

视图详解 一、视图的概念二、视图的常用操作2.1创建视图2.2查询视图2.3修改视图2.4 删除视图2.5向视图中插入数据 三、视图的检查选项3.1 cascaded&#xff08;级联 &#xff09;3.2 local(本地) 四、视图的作用 一、视图的概念 视图&#xff08;View&#xff09;是一种虚拟存…

数据结构 (22)哈夫曼树及其应用

前言 哈夫曼树&#xff08;Huffman Tree&#xff09;&#xff0c;又称最优二叉树或最优树&#xff0c;是一种特殊的二叉树结构&#xff0c;其带权路径长度&#xff08;WPL&#xff09;最短。 一、哈夫曼树的基本概念 定义&#xff1a;给定N个权值作为N个叶子结点&#xff0c;构…

Jenkins 的HTTP Request 插件为什么不能配置Basic认证了

本篇遇到的问题 还是因为Jenkins需要及其所在的OS需要升级&#xff0c;升级策略是在一台新服务器上安装和配置最新版本的Jenkins&#xff0c; 当前的最新版本是&#xff1a; 2.479.2 LTS。 如果需要这个版本的话可以在官方站点下载&#xff0c;也可以到如下地址下载&#xff1…

1.1 Beginner Level学习之“创建 ROS msg 和 srv”(第十节)

学习大纲&#xff1a; 1. msg 和 srv msg 文件是描述 ROS 消息字段的简单文本文件。它们用于为不同语言生成消息的源代码。srv 文件则描述了一个服务&#xff0c;包括两部分&#xff1a;请求和响应。Srv 文件用于生成服务的源代码。msg 文件存储在包的 msg 目录中。srv 文件存…

ubuntu中使用ffmpeg库进行api调用开发

一般情况下&#xff0c;熟悉了ffmpeg的命令行操作&#xff0c;把他当成一个工具来进行编解码啥的问题不大&#xff0c;不过如果要把功能集成进自己的软件中&#xff0c;还是要调用ffmpeg的api才行。 ffmpeg的源码和外带的模块有点太多了&#xff0c;直接用官网别人编译好的库就…

deepsort复现报错TypeError: tuple indices must be integers or slices, not tuple 解决

deepsort复现中遇到的TypeError: tuple indices must be integers or slices, not tuple问题的解决-CSDN博客 以上为参考教程。 复现的时候出现这个报错&#xff0c;搞了好久试了好多方法&#xff0c;包括降 scikit-learn版本&#xff0c;都不行&#xff0c;最后终于找到这个博…