首页 > 其他分享 >重头开始嵌入式第三十七天(数据结构 链表)

重头开始嵌入式第三十七天(数据结构 链表)

时间:2024-09-10 18:24:02浏览次数:9  
标签:tmp sll return SLinkNode 嵌入式 链表 第三十七 next

单向链表

单向链表是一种常见的数据结构。

一、结构组成

- 节点:单向链表由多个节点组成。每个节点包含两个部分,一个是存储数据的部分,可以存储各种类型的数据,如整数、字符、结构体等;另一个是指向下一个节点的指针,用于连接链表中的各个节点。

- 头指针:链表有一个特殊的指针称为头指针,它指向链表的第一个节点。如果链表为空,头指针为 NULL。

二、特点

- 动态性:单向链表的长度可以在运行时动态改变,可以根据需要随时添加或删除节点。

- 内存分配:节点通常是在运行时动态分配内存,可以在堆上使用诸如 malloc (在 C 语言中)或 new (在 C++中)来分配内存空间。

- 遍历方式:只能从链表的头节点开始,沿着指向下一个节点的指针依次访问各个节点,直到到达链表的末尾(即下一个指针为 NULL)。

三、基本操做

- 插入节点:可以在链表的头部、尾部或中间位置插入新的节点。插入操作需要修改相应节点的指针,使其指向新插入的节点。

- 删除节点:根据特定条件删除链表中的节点。删除操作也需要调整相应节点的指针,以保持链表的连续性。

- 查找节点:可以遍历链表查找满足特定条件的节点。

单向链表在很多场景下都有广泛应用,比如实现栈、队列等数据结构,以及在各种算法和程序中进行动态数据存储和管理。

创建ADT

typedef struct person {
    char name[32];
    char sex;
    int age;
    int score;
}DATATYPE;

typedef struct node {
    DATATYPE data;
    struct node *next;
}SLinkNode;

typedef struct list {
    SLinkNode *head;
    int clen;
}SLinkList;

1.创建链表

SLinkList * CreateSLinkList()
{

    SLinkList* sll = (SLinkList*) malloc(sizeof(SLinkList));
    if(NULL == sll)
    {
        perror("CreateSLinkList malloc");
        return NULL;
    }
    sll->head = NULL;
    sll->clen = 0 ;
    return sll;
}

2.头插数据

int InsertHeadSLinkList(SLinkList* sll,DATATYPE *data)
{
    SLinkNode* newnode = (SLinkNode*)malloc(sizeof(SLinkNode));
    if(NULL == sll)
    {
        perror("inserthead malloc");
        return 1;
    }

    memcpy(&newnode->data ,data,sizeof(DATATYPE));
    newnode->next = NULL;

    if(IsEmptySLinkList(sll))
    {
        sll->head = newnode;
    }
    else
    {
         newnode->next = sll->head;
         sll->head = newnode;
    }
    sll->clen++;
    return 0;
}

3.删除数据

int DeleteSLinkList(SLinkList*sll,FUN fun,void* arg)
{

//待删除节点的前一个指针
  SLinkNode*prev = NULL;
  SLinkNode*tmp = sll->head;
  int len = GetSizeSLinkList(sll);
  if(len == 1)
  {
    free(sll->head);
    sll->head = NULL;
    sll->clen = 0 ;
    return 0;
  }
  //至少2个节点
  while(1)
   {
    if(fun(&tmp->data,arg))
    {
      if(prev)
      {
        prev->next = tmp->next;
      }
      else
      {
       sll->head = tmp->next;
      }
      free(tmp);
      sll->clen--;
      return 0;
    }
    prev = tmp;
    tmp = tmp->next;
    if(NULL == tmp)
    {
        //删除失败
        //return 1;
        break;
    }
  }
  return 1;
}

4.更改数据

int ModifySlinkList(SLinkList*sll,FUN fun,void* arg,DATATYPE*newdata)
{

    SLinkNode* tmp= FindSlinkList(sll,fun, arg);
    if(NULL == tmp)
    {
        fprintf(stderr,"can find\n");
        return 1;
    }
    else
    {
        memcpy(&tmp->data,newdata,sizeof(DATATYPE));
    }
    return 0;
}

5.清空链表

int DestroySLinkList(SLinkList *sll) {
  SLinkNode *tmp = sll->head;
  while (1) {
    tmp = sll->head;
    if (!tmp)
      break;
    sll->head = sll->head->next;
    free(tmp);
  }
  free(sll);
  return 0;
}

6.查找数据

SLinkNode * FindSlinkList(SLinkList*sll,FUN fun,void* arg)
{

    SLinkNode* tmp = sll->head;
    int len = GetSizeSLinkList(sll);
    int i =  0;
    for(i=0;i<len;i++)
    {
        //if(0==strcmp(tmp->data.name,name))
        if(fun(&tmp->data,arg))
        {
            return tmp;
        }
        tmp = tmp->next;
    }
    return NULL;
}

7.尾插数据

int InserTailSlinkList(SLinkList* sll,DATATYPE *data)
{
    SLinkNode* newnode = (SLinkNode*)malloc(sizeof(SLinkNode));
    SLinkNode* tmp=sll->head;
    if(NULL == sll)
    {
        perror("inserthead malloc");
        return 1;
    }

    memcpy(&newnode->data ,data,sizeof(DATATYPE));
    newnode->next = NULL;

    if(IsEmptySLinkList(sll))
    {
        sll->head = newnode;
    }
    else
    {
        while(tmp->next)
            tmp=tmp->next;
         tmp->next=newnode;
    }
    sll->clen++;
    return 0;
}

8.按位插入

int InserPosSlinkList(SLinkList* sll,DATATYPE *data,int pos)
    {

        int len = GetSizeSLinkList(sll);
        if(pos<0 || pos > len)
        {
            return 1;

        }

        if(0 == pos)
        {

            return InsertHeadSLinkList(sll,data);

        }
        else if(pos == len)
        {

            return InserTailSlinkList(sll,data);
        } else // mid
        {
          int i = 0;
          SLinkNode *prev = sll->head;
          for (i = 0; i < pos - 1; i++) {
            prev = prev->next;
          }
          SLinkNode *newnode = malloc(sizeof(SLinkNode));
          if (NULL == newnode) {
            perror("insert pos malloc");
            return 1;
          }
          memcpy(&newnode->data, data, sizeof(DATATYPE));
          newnode->next = NULL;

          newnode->next = prev->next;
          prev->next = newnode;
        }
        sll->clen++;
        return 0;
    }

9.打印数据

int ShowSLinkList(SLinkList*sll)
{
    SLinkNode* tmp = sll->head ;
    while(tmp)
    {
        printf("name:%s score:%d\n",tmp->data.name ,tmp->data.score);
        tmp= tmp->next ;//i++
    }
    return 0;
}

标签:tmp,sll,return,SLinkNode,嵌入式,链表,第三十七,next
From: https://blog.csdn.net/qq_64792908/article/details/142103138

相关文章

  • 数据结构—链表
    一:链表1、数组是连续的内存空间;而链表可以不一定是连续的内存空间2、单端链表;从前一个元素指向后一个元素3、链表的功能(1)访问o(n):数组是通过下表或者索引访问元素;链表是通过next指针以此递归的进行查询判断(2)搜索o(n):从头部遍历;知道找到位置(3)插入o(1):(4)删除o(1):4、特......
  • 每日算法随笔:反转链表 II
    明白了!下面我将基于你给的两种方法来详细解释题解,并展示每一步的变化过程。题解:反转链表II这道题要求我们反转链表中从第left个节点到第right个节点的部分,返回反转后的链表。我们会使用两种方法:递归和迭代。示例解析示例1:输入:head=[1,2,3,4,5],left=2,ri......
  • 每日算法随笔:反转链表
    题解:反转链表这道题目要求我们将一个单链表进行反转,返回反转后的链表。链表的反转可以通过迭代和递归两种方法来实现。下面我们将详细解释这两种方法,并通过例子演示每一步的变化过程。方法一:迭代法思路:我们用三个指针来完成链表的反转:prev表示前一个节点,curr表示当前节......
  • Java-实现双向环形链表
            双向链表是一种常用的数据结构,其特点是每个节点不仅包含数据,还持有指向前一个节点和后一个节点的指针。与普通双向链表不同的是,它的哨兵节点的prev指向最后一个元素,而最后一个元素的next指向哨兵。        具体双向普通链表可以参考我的上篇文章,这里......
  • [Python手撕]排序链表
    #Definitionforsingly-linkedlist.#classListNode:#def__init__(self,val=0,next=None):#self.val=val#self.next=nextclassSolution:defsortList(self,head:Optional[ListNode])->Optional[ListNode]:def......
  • 数据结构—单链表的基本操作
    目录1.单链表的初始化2.求表长操作3.按序号查找结点4.按值查找表结点5.插入结点操作6.删除结点操作7.头插法建立单链表8.尾插法建立单链表1.单链表的初始化 带头结点: boolInitList(LinkList&L){       //带头结点的单链表的初始化  L=(......
  • C ++ 从单链表到创建二叉树到二叉树的遍历(结构体)
    首先我们要了解二叉树的数据结构是什么,本质上二叉树是一个有两个节点的链表,我们先了解的单链表的相关定义单链表创建一个朴素的单链表#include<iostream>usingnamespacestd;structNode{intval;Node*next;Node(intx):val(x),next(nullptr){}......
  • 基于微信小程序与嵌入式系统的智能小车开发(详细流程)
    一、项目概述本项目旨在开发一款智能小车,结合微信小程序与嵌入式系统,提供实时图像处理与控制功能。用户可以通过微信小程序远程操控小车,并实时接收摄像头采集的图像。该项目解决了传统遥控小车在图像反馈和控制延迟方面的问题,提升了小车的智能化水平,适用于教育、科研和娱乐......
  • 嵌入式开发-如何快速定位到系统卡死的位置
       “靠,死机了”,在周遭满是噼噼啪啪的键盘声中,一声突兀的嚎叫响起。然后便是一阵手忙脚乱的各种log添加、代码查看、问题复现。这场景想想都觉得小心脏慌慌的。那么有什么办法能让我们遇到这种情况能稍微优雅一点,不至于发出杀猪般的嚎叫呢?这就是接下来要介绍的一个小方法......
  • 嵌入式笔面试小题
    嵌入式笔面试小题1、进程和线程有什么区别?2、循环控制条件关键字goto被经常使用,但是goto的使用场合为什么受到局限?3、字节对齐的理解,什么是字节对齐?4、堆与栈的区别?5、关键字const有什么含义?6、已知一个数组table,用一个宏定义,求出数据的元素个数?7、递归函数定义没有......