嵌入式学习数据结构(二)双向链表 内核链表

目录

双向链表

头文件

创建

遍历

头插

尾插

头删

尾删

查找指定节点

修改

删除指定结点

销毁

内核链表


双向链表

与单向链表相比,双向链表多增加一个指针域,指向前一个结点。

头文件

cpp 复制代码
#ifndef __DOULINK_H__
#define __DOULINK_H__
//双向链表存储的数据类型
typedef struct stu
{
    int id;
    char name[32];
    int score;
}Data_type_t;

/*双向链表的结点类型*/
typedef struct dounode
{
    Data_type_t data;
    struct dounode *ppre;  //指向前驱结点的指针
    struct dounode *pnext; //指向后继结点的指针
}DNode_t;

/*双向链表对象类型*/
typedef struct doulink
{
    DNode_t *phead;   //双向链表头结点地址
    int clen;         //双向链表结点个数
}DLink_t;


extern DLink_t *create_doulink();
extern int insert_doulink_head(DLink_t *pdlink, Data_type_t data);
extern int is_empty_doulink(DLink_t *pdlink);
extern void doulink_for_each(DLink_t *pdlink, int dir);
extern int insert_doulink_tail(DLink_t *pdlink, Data_type_t data);
extern int delete_doulink_head(DLink_t *pdlink);
extern int delete_doulink_tail(DLink_t *pdlink);
extern DNode_t *find_doulink(DLink_t *pdlink, char *name);
extern int change_doulink(DLink_t *pdlink, char *name, int score);
extern int delete_point_node(DLink_t *pdlink, char *name);
extern void destroy_doulink(DLink_t **ppdlink);

#endif

创建

cpp 复制代码
DLink_t *create_doulink()
{
  DLink_t *pdlink = malloc(sizeof(DLink_t));
  if (NULL == pdlink)
    {
      printf("malloc error");
      return NULL;
    }
  pdlink->phead = NULL;
  pdlink->clen = 0;
 
  return pdlink;
}

遍历

cpp 复制代码
void doulink_for_each(DLink_t *pdlink, int dir)
{
  if (is_empty_doulink(pdlink))
    {
      return;
    }
  DNode_t *ptemp = NULL;
  ptemp = pdlink->phead;
  if (dir)
    {
      while (ptemp != NULL)
        {
          printf("%d,%s,%d\n", ptemp->data.id, ptemp->data.name,
                 ptemp->data.score);
          ptemp = ptemp->pnext;
        }
    }
  else
    {
      while (ptemp->pnext != NULL)
        {
          ptemp = ptemp->pnext;
        }
      while (ptemp != NULL)
        {
          printf("%d,%s,%d\n", ptemp->data.id, ptemp->data.name,
                 ptemp->data.score);
          ptemp = ptemp->ppre;
        }
    }
  printf("\n");
}

头插

cpp 复制代码
int insert_doulink_head(DLink_t *pdlink, Data_type_t data)
{
  DNode_t *pnode = malloc(sizeof(DNode_t));
  if (NULL == pnode)
    {
      printf("malloc error");
      return -1;
    }
  pnode->data = data;
  pnode->ppre = NULL;
  pnode->pnext = NULL;
  if (is_empty_doulink(pdlink))
    {
      pdlink->phead = pnode;
    }
  else
    {
      pnode->pnext = pdlink->phead;
      pdlink->phead->ppre = pnode;
      pdlink->phead = pnode;
    }
  pdlink->clen++;
}

尾插

cpp 复制代码
int insert_doulink_tail(DLink_t *pdlink, Data_type_t data)
{
  DNode_t *pnode = malloc(sizeof(DNode_t));
  if (NULL == pnode)
    {
      printf("malloc error");
      return -1;
    }
  pnode->data = data;
  pnode->pnext = NULL;
  pnode->ppre = NULL;
  if (pdlink->phead == NULL)
    {
      pdlink->phead = pnode;
    }
  else
    {
      DNode_t *ptemp = pdlink->phead;
      while (ptemp->pnext != NULL)
        {
          ptemp = ptemp->pnext;
        }
      ptemp->pnext = pnode;
      pnode->ppre = ptemp;
      pnode->pnext = NULL;
      pdlink->clen++;
    }
}

头删

cpp 复制代码
int delete_doulink_head(DLink_t *pdlink)
{
  if (pdlink->phead == NULL)
    {
      return -1;
    }
  else if (pdlink->phead->pnext == NULL)
    {
      DNode_t *ptemp = pdlink->phead;
      pdlink->phead = NULL;
      free(ptemp);
    }
  else
    {
      DNode_t *ptemp = pdlink->phead;
      pdlink->phead = ptemp->pnext;
      ptemp->pnext->ppre = NULL;
      free(ptemp);
      pdlink->clen--;
    }
}

尾删

cpp 复制代码
int delete_doulink_tail(DLink_t *pdlink)
{
  if (pdlink->phead == NULL)
    {
      return -1;
    }
  else if (pdlink->phead->pnext == NULL)
    {
      DNode_t *ptemp = pdlink->phead;
      pdlink->phead = NULL;
      free(ptemp);
      pdlink->clen--;
    }
  else
    {
      DNode_t *ptemp = pdlink->phead;
      while (ptemp->pnext != NULL)
        {
          ptemp = ptemp->pnext;
        }
      ptemp->ppre->pnext = NULL;
      free(ptemp);
      pdlink->clen--;
    }
}

查找指定节点

cpp 复制代码
DNode_t *find_doulink(DLink_t *pdlink, char *name)
{
    DNode_t *ptmp = pdlink->phead;
    while (ptmp != NULL)
    {
        if (0 == strcmp(ptmp->data.name, name))
        {
            return ptmp;
        }
        ptmp = ptmp->pnext;
    }
    return NULL;
}

修改

cpp 复制代码
int change_doulink(DLink_t *pdlink, char *name, int score)
{
    DNode_t *ptmp = find_doulink(pdlink, name);
    if (NULL == ptmp)
    {
        return -1;
    }
    ptmp->data.score = score;
    return 0;
}

删除指定结点

cpp 复制代码
int delete_point_node(DLink_t *pdlink, char *name)
{
    DNode_t* pnode = find_doulink(pdlink, name);
    if (NULL == pnode)
    {
        return -1;
    }

    if (pnode == pdlink->phead)
    {
        delete_doulink_head(pdlink);
    }
    else if (NULL == pnode->pnext)
    {
        delete_doulink_tail(pdlink);
    }
    else
    {
        pnode->ppre->pnext = pnode->pnext;
        pnode->pnext->ppre = pnode->ppre;
        free(pnode);
        pdlink->clen--;
    }

    return 0;

}

销毁

cpp 复制代码
void destory_doulink(DLink_t *pdlink)
{
  DNode_t *ptemp = pdlink->phead;
  if (ptemp == NULL)
    {
      free(pdlink);
    }
  else
    {
      while (ptemp != NULL)
        {
          ptemp = ptemp->pnext;
          delete_doulink_head(pdlink);
        }
      free(pdlink);
    }
  printf("Destory pdlink\n");
}
void destroy_doulink(DLink_t **ppdlink)
{
    while (!is_empty_doulink(*ppdlink))
    {
        delete_doulink_head(*ppdlink);
    }
    free(*ppdlink);
    *ppdlink = NULL;
}

内核链表

无数据域,只有指针域,双向循环链表,不再将数据存储到链表节点中,而是将节点嵌入到存储的数据中。

offset-of:获取内核链表中链表结点到结构体起始位置的偏移量。

container-of:通过偏移量获取结构体首地址(节点首地址-偏移量)。

相关推荐
xxjj998a几秒前
如何安装linux版本的node.js
linux·运维·node.js
zzb15807 分钟前
Android Activity 与 Intent 学习笔记
android·笔记·学习
Engineer邓祥浩9 分钟前
JVM学习笔记(12) 第四部分 程序编译与代码优化 第11章 后端编译与优化
jvm·笔记·学习
Not Dr.Wang42219 分钟前
基于matlab的控制系统奈氏图及其稳定性分析
数据结构·算法·matlab
AC赳赳老秦23 分钟前
测试工程师:OpenClaw自动化测试脚本生成,批量执行测试用例
大数据·linux·人工智能·python·django·测试用例·openclaw
路溪非溪31 分钟前
Wireshark抓取以太网MAC帧并进行分析
linux·网络·驱动开发·wireshark
rainbow72424435 分钟前
AI学习路线分享:通用型认证与算法认证学习体验对比
人工智能·学习·算法
夜瞬42 分钟前
NLP学习笔记10:Transformer 架构——从编码器、解码器到自注意力
笔记·学习·自然语言处理
像一只黄油飞1 小时前
第二章-04-数据类型
笔记·python·学习·零基础
elseif1231 小时前
初学者必背【考点清单(大全)】【上篇】
开发语言·c++·笔记·学习·循环结构·分支结构·考纲