从零开始的嵌入式系统开发学习Day9(数据结构)

2023-05-16

目录

一、单链表

1.1 概念

 1.2 单链表的操作

1.2.1 定义结点结构体

1.2.2 创建一个空的单链表

1.2.3 头插法插入数据

1.2.4 遍历单链表

 1.2.5 尾插法插入数据

1.2.6 判断单链表是否为空

1.2.7 头删法删除数据(返回删除的数据)

1.2.8 按照数据修改数据

1.2.9 按照位置查找数据

1.2.10 按照数据查找位置

1.2.11 按照位置插入数据

1.2.12 直接插入排序

练习:实现单链表的反转

练习:单链表的整表删除

二、单向循环链表

2.1 概念

2.2 单向循环链表的操作

2.2.1 定义结点结构体

2.2.2 创建一个空的单向循环链表

2.2.3 插入数据

2.2.4 遍历循环单向链表

2.2.5 删除头结点

2.2.6 去头结点遍历循环链表


一、单链表

1.1 概念

        单链表:线性表的链式存储

                线性表:一对一的关系

                链式存储:不需要在内存中开辟一段连续的内存空间,所以每一个数据不再是一个基本数据,而是由两部分组成,数据域和指针域,数据域保存数据,指针域保存下一个结点的地址。

        单链表:就是单向链表,前者结点可以找到后者结点,但是后者无法找到前者。

 1.2 单链表的操作

1.2.1 定义结点结构体

#ifndef _LINKLIST_H_
#define _LINKLIST_H_
#include <stdio.h>
#include <stdlib.h>
//定义数据类型
typedef int DataType;
//定义结点结构体
typedef struct linklist
{
    DataType data; //数据域
    struct linklist *st;    //指针域,为了能够操作后面结点
                            //所以指针的类型为当前结构体的类型
}linklist;


#endif

1.2.2 创建一个空的单链表

 

//创建一个空的单链表
linklist* LinkListCreate()
{
    //定义一个头结点,在堆区开辟空间
    linklist *head = (linklist *)malloc(sizeof(linklist));
    //初始化指针域标识为空
    head->next = NULL;
    return head;
}

1.2.3 头插法插入数据

//头插法插入数据
void LinkListInsert(linklist *head,DataType value)
{
    //开辟空间,分配一个新的结点
    linklist *tmp = (linklist *)malloc(sizeof(linklist));
    tmp->next = NULL;
    tmp->data = value;
    //将要插入的结点的指针域指向第一个结点
    //第一个结点的地址:head->next
    //新插入结点的指针域:tmp->next
    tmp->next = head->next;
    //头结点的指针域保存要插入的结点的地址
    //头结点的指针域:head->next
    //新插入结点的地址:tmp
    head->next = tmp;
    return;
}

1.2.4 遍历单链表

//遍历单链表
void LinkListPrint(linklist *head)
{
    //定义一个指针保存第一个结点的地址
    linklist *p = head;
    while (p->next != NULL)
    {
        //p指向下一个结点(p保存下一个结点的地址)
        p = p->next;
        //打印数据
        printf("%d ",p->data);   
    }
    putchar(10);
}

 1.2.5 尾插法插入数据

//尾插法插入数据
void LinkListInsertTail(linklist *head,DataType value)
{
    linklist *tmp = (linklist *)malloc(sizeof(linklist));
    tmp->next = NULL;
    tmp->data = value;
    //找到最后一个结点
    linklist *p = head;
    while (p->next != NULL)
    {
        p = p->next;
    }
    //将新插入的结点保存在最后一个结点的后面
    p->next = tmp;
    //将新插入的结点的指针域指向NULL
    tmp->next = NULL;
    return;
}

1.2.6 判断单链表是否为空

//判断单链表是否为空
int LinkListIsEmpty(linklist *head)
{
    return head->next == NULL ? 1 : 0;
}

1.2.7 头删法删除数据(返回删除的数据)

//头删法删除数据(返回删除的数据)
DataType LinkListDelete(linklist *head)
{
    if(LinkListIsEmpty(head))
    {
        printf("单链表为空,删除失败!\n");
        return (DataType)-1;
    }
    DataType value;
    value = head->next->data;
    linklist *tmp = head->next;
    head->next = head->next->next;
    free(tmp);
    tmp = NULL;
    return value;
}

1.2.8 按照数据修改数据

//按照数据修改数据
void LinkListUpdateByData(linklist *head,DataType OldValue,DataType NewValue)
{
    if(LinkListIsEmpty(head))
    {
        printf("单链表为空,修改失败!\n");
        return;
    }
    linklist *p = head;
    int flags = 0;
    while (p->next != NULL)
    {
        if(p->data == OldValue)
        {
            p->data = NewValue;
            flags = 1;
        }
        p = p->next;
    }
    if (flags == 0)
    {
        printf("修改失败,数据%d不存在",OldValue);
    }
    return;
}

1.2.9 按照位置查找数据

//按照位置查找数据
DataType LinkListSearchByPos(linklist *head,int pos)
{
    if(pos < 1)
    {
        printf("查找失败,位置错误!\n");
        return (DataType)-1;
    }
    else
    {
        linklist *p = head;
        int i;    
        for(i = 0;i < pos;i++)
        {
            if(p->next == NULL)
            {
                printf("位置有误!\n");
                return (DataType)-1;
            }
            p = p->next;
        }
        return p->data;
    }
}

1.2.10 按照数据查找位置

//按照数据查找位置
int LinkListSearchByData(linklist *head,DataType value)
{
    if(LinkListIsEmpty(head))
    {
        printf("查找失败,单链表为空!\n");
        return -1;
    }
    else
    {
        int i = 0;
        linklist *p =head;
        while (p->next != NULL)
        {
            if (p->data != value)
            {
                p = p->next;
                i++;
            }
            else
            {
                printf("查找成功,位置是第%d个",i);
                return 0;
            }
        }
        printf("查找失败,数据%d不存在",value);
        return 0;
    }   
}

1.2.11 按照位置插入数据

//按照位置插入数据
void LinkListInsertByPos(linklist *head,int pos,DataType vaule)
{
    if(pos < 1)
    {
        printf("插入失败,位置错误!\n");
        return;
    }
    linklist *tmp = (linklist *)malloc(sizeof(linklist));
    tmp->data = vaule;
    tmp->next = NULL;
    if(LinkListIsEmpty(head))
    {
        tmp->next = head->next;
        head->next = tmp;
    }
    else
    {
        linklist *p = head;
        int i;    
        for(i = 0;i < pos;i++)
        {
            if(p->next == NULL)
            {
                printf("位置有误!\n");
            }
            p = p->next;
        }
        tmp->next = p->next;
        p->next = tmp;
    }
}

1.2.12 直接插入排序

//直接插入排序
void LinkListInsertSort(linklist *head,DataType value)
{
    linklist *tmp = (linklist *)malloc(sizeof(linklist));
    tmp->data = value;
    tmp->next = NULL;
    linklist *p = head;
    while (p->next != NULL && p->next->data < tmp->data)
    {
        p = p->next;
    }
    tmp->next = p->next;
    p->next = tmp;
}

练习:实现单链表的反转

h1: 10->20->30->40->NULL

......

h2:40->30->20->10->NULL

//实现单链表的翻转
void LinkListReverse(linklist *head)
{
    if(LinkListIsEmpty(head))
    {
        printf("翻转失败,单链表为空!\n");
        return;
    }
    else
    {
        linklist *p = NULL,*q = NULL;
        p = head->next;
        head->next = NULL;
        while (p != NULL)
        {
            q = p;
            p = p->next;
            q->next = head->next;
            head->next = q;
        }
        
    }
}
//实现单链表的翻转2
void LinkListReverse2(linklist *head)
{
    if(LinkListIsEmpty(head))
    {
        printf("翻转失败,单链表为空!\n");
        return;
    }
    else
    {
        linklist *tmp = LinkListCreate();
        linklist *p = head;
        DataType value;
        while (p->next != NULL)
        {
            value = LinkListDelete(head);
            LinkListInsert(tmp,value);
        }
        head->next = tmp->next;
    }
}

练习:单链表的整表删除

//单链表的整表删除
void LinkListClean(linklist *head)
{
    linklist *p = NULL,*q = NULL;
    p = head->next;
    while (p != NULL)
    {
        q = p->next;
        free(p);
        p = q;
    }
    head->next = NULL;
}

二、单向循环链表

2.1 概念

2.2 单向循环链表的操作

2.2.1 定义结点结构体

//定义结点结构体
typedef struct looplist
{
    DataType value;
    struct looplist *next;
}looplist;

2.2.2 创建一个空的单向循环链表

//创建一个空的单向循环链表
looplist* LoopListCreate()
{
    looplist *head = (looplist *)malloc(sizeof(looplist));
    head->next = head;
    return head;
}

2.2.3 插入数据

//插入数据
void LoopListInsert(looplist *head,DataType value)
{
    looplist *tmp = (looplist *)malloc(sizeof(looplist));
    tmp->data = value;
    tmp->next = NULL;
    tmp->next = head->next;
    head->next = tmp;
    return;
}

2.2.4 遍历循环单向链表

//遍历单向循环链表
void LoopListPrint(looplist *head)
{
    looplist *p = head;
    while (p->next != head)
    {
        p = p->next;
        printf("%d ",p->data);
    }
    putchar(10);
    return;
}

2.2.5 删除头结点

//删除头结点
looplist* LoopListDeleteHead(looplist *head)
{
    looplist *p = head;
    while (p->next != head)
    {
        p = p->next;
    }
    p->next = head->next;
    free(head);
    head = NULL;
    return p->next;
}

2.2.6 去头结点遍历循环链表

//去头结点遍历单向循环链表
void LoopListPrint2(looplist *head)
{
    looplist *p = head;
    while (p->next != head)
    {
        printf("%d ",p->data);
        p = p->next;
    }
    printf("%d ",p->data);
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从零开始的嵌入式系统开发学习Day9(数据结构) 的相关文章

  • Ubuntu中apt update和upgrade的区别

    原文链接 xff1a https blog csdn net CSDN duomaomao article details 77802673 简要说明 xff1a apt update xff1a 只检查 xff0c 不更新 xff08 已
  • Java中的信号量(Semaphore)

    初识Semaphore 信号量 xff0c 也可以称其为 信号灯 xff0c 它的存在就如同生活中的红绿灯一般 xff0c 用来控制车辆的通行 在程序员眼中 xff0c 线程就好比行驶的车辆 xff0c 程序员就可以通过信号量去指定线程是否
  • USB 2.0_ser!或者U232-P9 型USB转串Win7 32位或64位驱动 以及 USB转串串口序号查看和设置

    前几天叫同事在电脑城买了个USB转串数据线 xff0c 但是回来后在网上找了很多驱动都不行 觉得这个问题花了不少时间的 xff0c 我也拆开了 xff0c 打算按照芯片型号找驱动 xff0c 但是看不到芯片型号 现在终于找到合适的了 把这个
  • 《Java核心技术卷1》

    第3章 Java的基础程序设计结构 整型 用int类型表示一百万可以这么写 xff08 since 1 7 xff09 span class token keyword int span a span class token operato
  • voxl-flight quick start

    voxl flight 官方地址 xff1a https www modalai com 硬件及接口 两个版本 Snapdragon 821 xff1a 四核最高2 15GH xff0c GPU xff0c 2xDSP 视频支持 xff1a
  • 零基础如何学习优达学城的《无人驾驶入门》?

    因为感兴趣 xff0c 而且看好无人驾驶行业 xff0c 我学习了优达学城的 无人驾驶入门 课程 最近整理了无人驾驶领域的资料 xff0c 写成文章分享给大家 作为系列文章的第一篇 xff0c 我想介绍一下 无人驾驶入门 这门课 xff0c
  • realsense D435 标定(calibration)

    realsense D435 标定 文章目录 realsense D435 标定1 确定是否需要标定设备信息步骤操作打印标定目标开启标定程序 校正结果展示比较 文档 1 确定是否需要标定 工具 Depth Quality Tool 要求 将
  • 如何在linux执行PHP文件

    1 刚导入到linux系统中文件是没有可执行权 2 首先赋予文件可执行权限 chmod 43 x 文件名 例如 xff1a chomd 43 x czrkdjb php 如果要用 czrkdjb php执行 xff0c 需要在czrkdjb
  • 阿里P8大佬亲自讲解!写给程序员的Flutter详细教程,灵魂拷问

    我们程序员经常迷茫于有太多东西要学 xff0c 有些找不到方向 不知所措 很多程序员都愿意说 xff0c 我想变得更好 xff0c 但是更好是什么却很模糊 xff0c 同时我们又不知道该怎么样去做 我们的生命如此短暂 xff0c 作为程序员
  • VSCode 连接远程服务器使用图形化界面(GUI)

    1 基本环境 本地电脑系统 xff1a window10 远程服务器系统 xff1a Ubuntu18 04 2 VSCode版本 xff1a 1 51 1 2 问题描述 vscod提供了优秀的远程连接插件 xff08 Remote SSH
  • curl 命令大全及常用实例

    一 xff0c curl命令参数 a append 上传文件时 xff0c 附加到目标文件 A user agent lt string gt 设置用户代理发送给服务器 anyauth 可以使用 任何 身份验证方法 b cookie lt
  • 关于putty不能连接虚拟机的问题解决

    一 首先需要ping 一下 xff0c 看是否能ping通 xff0c 如果正常进入下一步 二 进入虚拟机终端输入 ssh localhost 如果提示 ssh connect to host localhost port 22 Conne
  • postman进行http接口测试

    HTTP的接口测试工具有很多 xff0c 可以进行http请求的方式也有很多 xff0c 但是可以直接拿来就用 xff0c 而且功能还支持的不错的 xff0c 我使用过的来讲 xff0c 还是postman比较上手 优点 xff1a 1 支
  • Linux系统迁移(将配置好的系统安装到其它电脑上)

    Linux系统迁移 说在前面 xff1a 下面有几个教程链接 xff0c 我都是通过这几个链接来完成的系统备份与系统恢复 并且遇到过一些问题 xff0c 踩过一些坑 建议先看完我的说明再进行操作 xff0c 少走弯路 没有图是因为下面分享的
  • 搭建 公网FTP服务器 外网访问

    我是在ubuntu 20 04 上配置的 xff0c 需要用到公网IP 没有公网IP的 xff0c 可以考虑花生壳这类应用来做内网穿透 1 配置FTP服务器 安装vsftpd sudo apt install vsftpd sudo vim
  • clang-format配置与使用

    clang format配置与使用 参考教程 1 安装 下载clang format xff0c 设置环境变量 我使用的是vscode扩展中的clang format 位于 xff1a extensions ms vscode cpptoo
  • AI一般是用来制作什么的

    AI一般用来制作logo 分页 xff0c 海报等等 面板堆栈的话就是很多功能堆放的位置 一般打印出来的话用cmyk模式 如果是在web端的话用RGB模式 xff0c 因为cmyk模式在你进行存储的过程中颜色可能会丢失 出血值就是在你打印东
  • Eclipse安装插件的三种方式

    本文介绍Eclipse插件的安装方法 Eclipse插件的安装方法大体有三种 xff1a 直接复制 使用link文件 xff0c 以及使用eclipse自带的图形界面的插件安装方法 AD xff1a 做为当下最流行的开源IDE之一 xff0
  • 获取realsense内参

    文章目录 xff11 xff0e 无畸变 xff12 xff0e Brown Conrady 畸变模型3 Opencv 里畸变图像矫正过程 xff11 xff0e 无畸变 相机内参包括相机矩阵参数和畸变系数 相机内参矩阵为3 3的矩阵 xf
  • 十年研发经验工程师的嵌入式学习书籍大推荐

    从事嵌入式研发行业十年 xff0c 认为学习就是要不断的吸纳知识 xff0c 在研发过程中 xff0c 经常会遇到一些问题 xff0c 这种发现问题并解决问题的过程就是进步 为什么选择学习嵌入式 xff1f 嵌入式系统无疑是当前最热门最有发

随机推荐

  • js手机号正则表达式验证

    看到网上很多代码 都很复杂 xff0c 还包括以中文开头的86 xff0c 17951 xff0c 其实谁会填这么多 xff0c 无非是检验一下他们是否位数对不对 xff0c 开头有没有写错而已 下面我们从百度百科的手机号码历程来看 xff
  • 正则验证匹配中文姓名全部源字符串

    这个是验证匹配中文姓名的全部源串 xff0c 在网上找了很久 xff0c 大都是验证匹配含有中文 xff0c 就在网上某人提供的正则的基础上修改成了验证所填姓名的每个字符 xff0c 只有都匹配才能验证通过 该正则为 xff1a u4e00
  • 域名,网站名和URL区别

    要写一个正则表达式来验证输入域名是否有正确 xff0c 一直以为例如http www baidu com类似于这种才是网站域名 xff0c 经过百度才发现自己的认知是错误的 以下转载于百度经验 xff1a http jingyan baid
  • 23种设计模式(1)-Facade设计模式

    前记 曾经我遇见的一个需求是这样的 xff0c 接口A有个方法void methodA xff0c 类B需要实现接口A的methodA 方法 xff0c 并且在类B中需要把methodA 方法内部处理逻辑获得的结果利用C类实例的某个方法进行
  • Linux CentOS 7安装GNOME图形界面并设置默认启动方式

    为hadoop集群做准备 xff0c 没有多台电脑 xff0c 也只能委屈我这渣渣电脑了 在我的物理机上安装虚拟机 xff0c 再在虚拟机里面虚拟出两台电脑 xff0c 安装两个linux操作系统 1 xff0c 电脑太渣 xff0c 安装
  • dubbo学习资源

    简介 xff1a 项目有使用dubbo xff0c 以此需要学习一下 xff0c 搜集学习资源 一 xff0c 博客资源 1 xff0c dubbo学习 2 xff0c dubbo配置
  • 使用CSS3的box-sizing属性解决div宽高被内边距撑开的问题

    有时我们会给页面的元素 xff08 比如div xff09 设置个固定的高度或宽度 但如果给这个div又设置了内边距或者边框的话 xff0c 那么这个div就会被撑大 也就是其实际的尺寸变成了 xff1a 设置的宽高尺寸 43 内边距 43
  • 博客搬家:https://blog.csdn.net/u012995888

    本博客文章有些乱 xff0c 多有转载 xff0c 现在主要在另一CSDN账号更新原创文章 xff0c 点击查看博客主页 另外 xff0c 本博客后续可能会重新整理栏目 xff0c 更新高质量文章 xff0c 谢谢关注 xff01
  • C++ 常用设计模式(学习笔记)

    1 工厂模式 工厂模式 xff1a 简单工厂模式 工厂方法模式 抽象工厂模式 1 简单工厂模式 xff1a 主要特点是需要在工厂类中做判断 xff0c 从而创造相应的产品 xff0c 当增加新产品时 xff0c 需要修改工厂类 typede
  • 通过更新显卡驱动和内核,解决linux启动时在starting atd: [ok]停止的问题

    说得有些复杂 xff0c 你可以不用理会这些 xff0c 直接执行我罗列的那几个命令就行了 方法一 xff1a 网上有说In some cases the new install Gforce Drivers do not supporte
  • Streamedian/html5_rtsp_player接海康视频遇到的坑

    Streamedian是一套能够让浏览器免插件播放RTSP的项目 安装了其官方的server端后有一个demo 如图 xff0c 在输入处输入红框格式的RTSP地址 xff0c 如官方的demo地址 xff1a rtsp 184 72 23
  • 文档与笔记利器 reStructuredText 和 Sphinx

    原文http qixinglu com archives note tools restructuredtext sphinx 文档与笔记利器 reStructuredText 和 Sphinx 28六 2011 作者 投稿 转载 本文采用
  • 关于递归的问题:无限递归

    当你在写递归的时候 xff0c 可能会出现运行不出结果来 xff0c 此时你应该试着看看会不会出现无限递归的问题 xff0c 如果有的话 xff0c 你可以在前面增加一个判断语句 xff0c 满足条件进入执行相关操作与递归 xff0c 但在
  • 无人机路径规划1:orbslam2+VIO

    无人机路径规划1 xff1a orbslam2 43 VIO 安装XTDRONE平台 https www yuque com xtdrone manual cn basic config ros基本操作 ros中文版教程 http wiki
  • 无人机路径规划2 vins_fusion + rtab_map学习

    导航过程中的tf Map gt odom gt base footprint gt base link odom里程计 odom tf base footprint gt base link xff1a robot state publis
  • 无人机路径规划3:ego-planner三维运动规划实现

    XTDrone实现ego planner三维运动规划 编译ego palnner span class token function cp span r XTDrone motion planning 3d ego planner catk
  • XTDRONE:ego_planner三维运动规划

    ros常用消息类型 xff1a https blog csdn net xhtchina article details 119707553 iris 0 ego transfer话题在 XTDrone motion planning 3d
  • 无人机运动规划4:ego-swarm无人机群运动规划

    配置 启动python脚本生成多机launch文件 span class token builtin class name cd span XTDrone coordination launch generator python3 gene
  • Promethues: swarm_control解读

    标签可以对节点分组 xff0c 具有 ns 属性 xff0c 可以让节点归属某个命名空间 lt group ns 61 34 iris 0 34 gt lt group ns 61 span class token string 34 ir
  • 从零开始的嵌入式系统开发学习Day9(数据结构)

    目录 一 单链表 1 1 概念 1 2 单链表的操作 1 2 1 定义结点结构体 1 2 2 创建一个空的单链表 1 2 3 头插法插入数据 1 2 4 遍历单链表 1 2 5 尾插法插入数据 1 2 6 判断单链表是否为空 1 2 7 头