Linux学习-数据结构(链表)

1.双向链表

1.空链表的创建

参考单向链表

cs 复制代码
linknode *creat_empty_doulist(void)
{
    linknode *ptmpnode = NULL;

    ptmpnode = malloc(sizeof(linknode));
    if(NULL == ptmpnode)
    {
        perror("fail to malloc");
        return NULL;
    }

    ptmpnode->pnext = NULL;
    ptmpnode->ppre = NULL;

    return ptmpnode;
}

2.头插法插入节点

参考单向链表

cs 复制代码
int insert_head_doulist(linknode *phead, datatype tmpdata)
{
    linknode *ptmpnode = NULL;
    //申请空间
    ptmpnode = malloc(sizeof(linknode));

    if(NULL == ptmpnode)
    {
        perror("fail to malloc");
        return -1;
    }

    ptmpnode->data = tmpdata;
    ptmpnode->pnext = phead->pnext;
    ptmpnode->ppre = phead;

    phead->pnext = ptmpnode;

    if(ptmpnode->pnext != NULL)
    {
       ptmpnode->pnext->ppre == ptmpnode;
    }
    
    return 0;
}

3.链表的遍历

参考单向链表

cs 复制代码
int show_doulist(linknode *phead)
{
    linknode *ptmpnode = NULL;

    ptmpnode = phead->pnext;
    while(ptmpnode != NULL)
    {
        printf("%d ", ptmpnode->data);
        ptmpnode = ptmpnode->pnext;
    }
    printf("\n");
    return 0;
}

4.链表的查询

参考单向链表

cs 复制代码
linknode *find_doulist(linknode *phead, datatype tmpdata)
{
    linknode *ptmpnode = NULL;

    ptmpnode = phead->pnext;

    while(ptmpnode->data != tmpdata)
    {
        if(ptmpnode == NULL || ptmpnode->pnext == NULL)
        {
            return NULL;
        }
        ptmpnode = ptmpnode->pnext;
    }

    return ptmpnode;
}

5.链表的修改

cs 复制代码
int update_doulist(linknode *phead, datatype olddata, datatype newdata)
{
    linknode *ptmpnode = NULL;

    ptmpnode = phead->pnext;
    while(ptmpnode->data != olddata)
    {
        if(ptmpnode == NULL || ptmpnode->pnext == NULL)
        {
            return 0;
        }
        ptmpnode = ptmpnode->pnext;
    }
    ptmpnode->data = newdata;

    return 0;
}

6.链表的删除

  • 找到要删除的节点
  • 让删除的节点的前一个节点的pnext等于要删除节点的后一个节点的地址
  • 让删除的节点的后一个节点的ppre等于要删除节点的前一个节点的地址
  • 释放删除的节点
cs 复制代码
int delete_doulist(linknode *phead, datatype tmpdata)
{
    linknode *ptmpnode = NULL;
    linknode *pfreenode = NULL;

    ptmpnode = phead->pnext;

    while(ptmpnode != NULL)
    {
        if(ptmpnode->data == tmpdata)
        {   
            ptmpnode->ppre->pnext = ptmpnode->pnext; 
            if(ptmpnode->pnext != NULL)
            {
                ptmpnode->pnext->ppre = ptmpnode->ppre;     
            }
            pfreenode = ptmpnode;
            ptmpnode = ptmpnode->pnext;
            free(pfreenode);
        }
        else
        {
            ptmpnode = ptmpnode->pnext;
        }
        
    }

    return 0;
}

7.链表的销毁

cs 复制代码
int destroy_doulist(linknode **pphead)
{
    linknode *ptmpnode = NULL;
    linknode *pfreenode = NULL;

    ptmpnode = *pphead;
    pfreenode = *pphead;

    while(pfreenode != NULL)
    {
        ptmpnode = ptmpnode->pnext;
        free(pfreenode);
        pfreenode = ptmpnode;
    }

    *pphead = NULL;

    return 0;
}

8.链表的尾插法

cs 复制代码
int insert_last_doulist(linknode *phead, datatype tmpdata)
{
    linknode *ptmpnode = NULL;
    linknode *pinsertnode = NULL;

    pinsertnode = malloc(sizeof(linknode));
    if(pinsertnode == NULL)
    {
        perror("fail to malloc");
        return -1;
    }

    ptmpnode = phead->pnext;
    while(ptmpnode->pnext != NULL)
    {
        ptmpnode = ptmpnode->pnext;
    }
    pinsertnode->ppre = ptmpnode;
    pinsertnode->data = tmpdata;
    pinsertnode->pnext = NULL;
    ptmpnode->pnext = pinsertnode;

    return 0;
}

2.循环链表

1.特点

  • 头节点的ppre指向链表的最后一个节点
  • 最后节点的pnext指向链表的第一个节点
    2.节点定义

与双向链表保持一致

cs 复制代码
typedef int datatype;

typedef struct node
{
    datatype data;
    struct node *ppre;
    struct node *pnext;
}linknode;

3.链表创建

cs 复制代码
linknode *creat_cirlist(void)
{
    linknode *ptmpnode = NULL;

    ptmpnode = malloc(sizeof(linknode));
    if(ptmpnode == NULL)
    {
        perror("fail to malloc");
        return NULL;
    }

    ptmpnode->pnext = ptmpnode;
    ptmpnode->ppre = ptmpnode;

    return ptmpnode;
}

4.链表的头插法

  • 申请空间
  • 存放数据
  • 将pnext赋值为空白节点的pnext
  • 将ppre指向前面的节点
  • 将前面的节点的pnext指向新申请的节点
  • 将空白节点的ppre指向新申请的节点
cs 复制代码
int insert_head_cirlist(linknode *phead, datatype tmpdata)
{
    linknode *ptmpnode = NULL;

    ptmpnode = malloc(sizeof(linknode));
    if(ptmpnode == NULL)
    {
        perror("fail to malloc");
        return -1;
    }

    ptmpnode->data = tmpdata;
    ptmpnode->pnext = phead->pnext;
    ptmpnode->ppre = phead;
    ptmpnode->ppre->pnext = ptmpnode;
    ptmpnode->pnext->ppre = ptmpnode;

    return 0;
}

5.链表的尾插法

cs 复制代码
int insert_tail_cirlist(linknode *phead, datatype tmpdata)
{
    linknode *ptmpnode = NULL;

    ptmpnode = malloc(sizeof(linknode));
    if(ptmpnode == NULL)
    {
        perror("fail to malloc");
        return -1;
    }

    ptmpnode->data = tmpdata;
    ptmpnode->pnext = phead;
    ptmpnode->ppre = phead->ppre;
    ptmpnode->ppre->pnext = ptmpnode;
    ptmpnode->pnext->ppre = ptmpnode;

    return 0;
}

6.链表的遍历

cs 复制代码
int show_cirlist(linknode *phead)
{
    linknode *ptmpnode = NULL;

    ptmpnode = phead->pnext;
    while(ptmpnode != phead)
    {
        printf("%d ",ptmpnode->data);
        ptmpnode = ptmpnode->pnext;
    }
    printf("\n");

    return 0;
}

7.链表的查找

cs 复制代码
linknode *find_cirlist(linknode *phead, datatype tmpdata)
{
    linknode *ptmpnode = NULL;

    ptmpnode = phead->pnext;
    while(ptmpnode != phead)
    {
        if(ptmpnode->data == tmpdata)
        {
            return ptmpnode;
        }
        ptmpnode = ptmpnode->pnext;
    }

    return NULL;
}

8.链表的修改

cs 复制代码
int update_cirlist(linknode *phead, datatype olddata, datatype newdata)
{
    linknode *ptmpnode = NULL;

    ptmpnode = phead->pnext;
    while(ptmpnode != phead)
    {
        if(ptmpnode->data == olddata)
        {
            ptmpnode->data = newdata;
        }
        ptmpnode = ptmpnode->pnext;
    }

    return 0;
}

9.链表的删除

cs 复制代码
int delete_tmpdata_cirlist(linknode *phead, datatype tmpdata)
{
    linknode *ptmpnode = NULL;
    linknode *pfreenode = NULL;

    ptmpnode = phead->pnext;
    while(ptmpnode != phead)
    {
        if(ptmpnode->data == tmpdata)
        {
            ptmpnode->ppre->pnext = ptmpnode->pnext;
            ptmpnode->pnext->ppre = ptmpnode->ppre;
            pfreenode = ptmpnode;
            ptmpnode = ptmpnode->pnext;
            free(pfreenode);
        }
        else
        {
            ptmpnode = ptmpnode->pnext;
        } 
    }

    return 0;
}

10.链表的销毁

cs 复制代码
int destroy_cirlist(linknode **pphead)
{
    linknode *ptmpnode = NULL;
    linknode *pfreenode = NULL;

    ptmpnode = (*pphead)->pnext;
    pfreenode = (*pphead)->pnext;

    while(ptmpnode != *pphead)
    {
        ptmpnode = ptmpnode->pnext;
        free(pfreenode);
        pfreenode = ptmpnode;
    }
    free(*pphead);
    *pphead = NULL;

    return 0;
}

3.内核链表

1.概念

  • Linux内核中所使用的一种链表结构
  • 使用同一种结构可以存放不同类型的链表
  • 普通链表:链表节点中包含数据
  • 内核链表:数据中包含链表节点
    2.结构
  • 创建:创建空白节点即可
  • 插入:申请节点,按照学习的循环链表插入即可(插入链表节点的首地址即数据节点首地址)
  • 访问节点:通过遍历找到每个节点的首地址,强制类型转换即可获得对应数据空间首地址
相关推荐
Boilermaker199217 小时前
[Java 并发编程] Synchronized 锁升级
java·开发语言
MM_MS17 小时前
Halcon变量控制类型、数据类型转换、字符串格式化、元组操作
开发语言·人工智能·深度学习·算法·目标检测·计算机视觉·视觉检测
C_心欲无痕17 小时前
ts - tsconfig.json配置讲解
linux·前端·ubuntu·typescript·json
꧁Q༒ོγ꧂18 小时前
LaTeX 语法入门指南
开发语言·latex
njsgcs18 小时前
ue python二次开发启动教程+ 导入fbx到指定文件夹
开发语言·python·unreal engine·ue
alonewolf_9918 小时前
JDK17新特性全面解析:从语法革新到模块化革命
java·开发语言·jvm·jdk
冰西瓜60018 小时前
国科大2025操作系统高级教程期末回忆版
linux
古城小栈18 小时前
Rust 迭代器产出的引用层数——分水岭
开发语言·rust
ghie909018 小时前
基于MATLAB的TLBO算法优化实现与改进
开发语言·算法·matlab
恋爱绝缘体118 小时前
2020重学C++重构你的C++知识体系
java·开发语言·c++·算法·junit