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

目录

双向链表

头文件

创建

遍历

头插

尾插

头删

尾删

查找指定节点

修改

删除指定结点

销毁

内核链表


双向链表

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

头文件

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

相关推荐
XiaoFan01213 小时前
免密批量抓取日志并集中输出
java·linux·服务器
●VON13 小时前
React Native for OpenHarmony:2048 小游戏的开发与跨平台适配实践
javascript·学习·react native·react.js·von
souyuanzhanvip13 小时前
ServerBox v1.0.1316 跨平台 Linux 服务器管理工具
linux·运维·服务器
ZH154558913113 小时前
Flutter for OpenHarmony Python学习助手实战:自动化脚本开发的实现
python·学习·flutter
xcLeigh13 小时前
Python入门:Python3 requests模块全面学习教程
开发语言·python·学习·模块·python3·requests
xcLeigh13 小时前
Python入门:Python3 statistics模块全面学习教程
开发语言·python·学习·模块·python3·statistics
我能坚持多久13 小时前
【初阶数据结构01】——顺序表专题
数据结构
GHL28427109014 小时前
分析式AI学习
人工智能·学习·ai编程
lpruoyu14 小时前
【Android第一行代码学习笔记】Android架构_四大组件_权限_持久化_通知_异步_服务
android·笔记·学习
野犬寒鸦14 小时前
从零起步学习并发编程 || 第六章:ReentrantLock与synchronized 的辨析及运用
java·服务器·数据库·后端·学习·算法