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

目录

双向链表

头文件

创建

遍历

头插

尾插

头删

尾删

查找指定节点

修改

删除指定结点

销毁

内核链表


双向链表

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

头文件

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:通过偏移量获取结构体首地址(节点首地址-偏移量)。

相关推荐
Irissgwe36 分钟前
进程间通信
linux·服务器·网络·c++·进程间通信
_李小白36 分钟前
【OSG学习笔记】Day 2: Hello Cow
笔记·学习
Wave84537 分钟前
数据结构—树
数据结构
ic爱吃蓝莓43 分钟前
数据结构 | HashMap原理
数据结构·学习·算法·链表·哈希算法
鹭天1 小时前
Langchain学习笔记
笔记·学习·langchain
创世宇图1 小时前
阿里云Alibaba Cloud Linux 4 LTS 64位生产环境配置-Nginx
linux·nginx
待续3012 小时前
OpenClaw 安装及使用教程(Windows / macOS / Linux)
linux·windows·macos
创世宇图2 小时前
Alibaba Cloud Linux 安装生产环境-mysql
linux·mysql
TEC_INO2 小时前
嵌入式 Linux 开发知识总结
linux·运维·服务器
liuyao_xianhui3 小时前
优选算法_分治_快速排序_归并排序_C++
开发语言·数据结构·c++·算法·leetcode·排序算法·动态规划