数据结构-双向链表-003

1双向链表

1.1链表结点结构体定义

c 复制代码
typedef struct student_data
{
    char name[32];
    char sex;
    int age;
}STU_DATA;
c 复制代码
typedef struct double_link_node
{
    STU_DATA data;//数据域
    struct double_link_node *ppre;//指向上一个结点的指针
    struct double_link_node *pnext;//指向下一个结点的指针
}DOUB_NODE;

1.2链表头结点结构体定义

c 复制代码
typedef struct double_link_head
{
    DOUB_NODE *phead;//指向首结点的指针
    int clen;//记录链表节点数量
}DOUB_HEAD;

1.3双向链表头结点创建

c 复制代码
/*=============双向链表创建头结点(创建空表)=========*/
void *create_double_link_list_head_node(void)
{
    DOUB_HEAD *phead=NULL;

    /*创建头结点空间*/
    phead=malloc(sizeof(DOUB_HEAD));
    if(NULL==phead)
    {
        perror("fail to malloc");
        return NULL;
    }

    /*头结点初始化*/
    phead->phead=NULL;
    phead->clen=0;

    return phead;
}

1.4双向链表结点创建

c 复制代码
/*=============双向链表创建新结点==============*/
void* create_double_link_list_new_node(STU_DATA data)
{
    DOUB_NODE *pnode=NULL;

    /*创建新结点空间*/
    pnode=malloc(sizeof(DOUB_NODE));
    if(NULL==pnode)
    {
        perror("fail to malloc");
        return NULL;
    }

    /*新结点初始化*/
    pnode->data = data;
    pnode->ppre=NULL;
    pnode->pnext=NULL;

    return pnode;
}

1.5链表非空判断

c 复制代码
/*=============双向链表非空判断==============*/
int is_empty_link(DOUB_HEAD *list)
{
    return NULL==list->phead;
}

1.6双向链表结点插入

1.6.1头插法

c 复制代码
/*=============双向链表头插法=================*/
int push_head_double_link_list(DOUB_HEAD *list, DOUB_NODE *pnode)
{
    if(NULL==list||NULL==pnode)
    {
        return -1;
    }

    if(is_empty_link(list))
    {
        list->phead=pnode;
    }
    else
    {
        pnode->pnext=list->phead;//初始化新结点的后继为旧的首结点
        list->phead->ppre=pnode;//更新首结点的前驱结点为新结点
        list->phead=pnode;//更新头结点的指向为新结点(因为此时新结点为新的首结点)
    }
    list->clen++;

    return 0;
}

1.6.2尾插法

c 复制代码
/*=============双向链表尾插法=================*/
int push_tail_double_link_list(DOUB_HEAD *list,DOUB_NODE *pnode)
{
    DOUB_NODE *ptmp=NULL;

    if(NULL==list||NULL==pnode)
    {
        return -1;
    }


    if(is_empty_link(list))
    {
        list->phead=pnode;
    }

    else
    {
        /*定义一个遍历指针,初始化为指向首结点*/
        ptmp=list->phead;
        while(1)
        {
            if(NULL==ptmp->pnext)
            {
                break;
            }

            ptmp=ptmp->pnext;
        }
        pnode->pnext=ptmp->pnext;//初始化新结点的后继结点为NULL(原来尾结点的指针域)
        ptmp->pnext=pnode;//更新尾结点的后继结点为新结点
        pnode->ppre=ptmp;//初始化新结点的前继结点为尾结点
    }

    list->clen++;

    return 0;
}

1.7双向链表遍历

1.7.1低配版本遍历

c 复制代码
/*=============双向链表遍历(原始版)===============*/
int double_list_for_each(DOUB_HEAD *list)
{
    DOUB_NODE *ptmp=NULL;

    /*判断空表*/
    if(is_empty_link(list))
    {
        return 0;
    }

    /*初始化遍历指针为指向首结点*/
    ptmp=list->phead;
    while(1)
    {
        if(NULL==ptmp)//如果是空表,也满足,如果遍历到链表末尾,也满足条件
        {
            break;
        }

        else
        {
            printf("%-10s\t%-10c\t%-10d\n",ptmp->data.name,ptmp->data.sex,ptmp->data.age);
            ptmp=ptmp->pnext;
        }

    }

    return 0;
}

1.7.2指定遍历方法的遍历

c 复制代码
/*=============双向链表遍历(改进版)===============*/
int double_list_for_each(DOUB_HEAD *list,int dir,void (*pfun)(DOUB_NODE *))
{
    return 0;
}

1.8双向链表结点删除

1.8.1头删法

c 复制代码
bug待改

1.8.2尾删法

c 复制代码
/*==========双向链表尾删法==========*/
int pop_tail_double_link_list(DOUB_HEAD *list)
{
    DOUB_NODE *ptmp=NULL;

    if(is_empty_link(list))
    {
        return 0;
    }

    ptmp=list->phead;
    while(1)
    {
        if(NULL==ptmp->pnext)
        {
            break;
        }

        ptmp=ptmp->pnext;
    }

    if(ptmp->ppre!=NULL)
    {
        ptmp->ppre->pnext=NULL;
    }
    else
    {
        list->phead=NULL;
    }
    free(ptmp);

    list->clen--;

    return 0;
}

1.9双向链表查找

c 复制代码

1.10双向链表修改

c 复制代码

1.11双向链表销毁

c 复制代码

1.12双向链表的其它操作

1.12.1单向链表逆序

c 复制代码

1.12.2双向链表查找中间结点

c 复制代码

1.12.3双向链表查找倒数第k个结点

c 复制代码

1.12.4双向链表删除指定结点

1.12.4.1单结点删除
c 复制代码
1.12.4.2多结点删除
复制代码
用于多个结点值相同的情况
c 复制代码

1.13单向链表排序

1.13.1双向链表排序-插入排序法

相关推荐
chao_7895 小时前
链表题解——两两交换链表中的节点【LeetCode】
数据结构·python·leetcode·链表
笑口常开xpr9 小时前
数 据 结 构 进 阶:哨 兵 位 的 头 结 点 如 何 简 化 链 表 操 作
数据结构·链表·哨兵位的头节点
凤年徐21 小时前
【数据结构初阶】单链表
c语言·开发语言·数据结构·c++·经验分享·笔记·链表
扫地的小何尚2 天前
NVIDIA Dynamo:数据中心规模的分布式推理服务框架深度解析
人工智能·分布式·microsoft·链表·语言模型·gpu
零叹2 天前
篇章六 数据结构——链表(二)
数据结构·链表·linkedlist
T1an-12 天前
【力扣链表篇】206.反转链表
算法·leetcode·链表
hqxstudying3 天前
JAVA容器
java·b树·链表
全栈凯哥5 天前
Java详解LeetCode 热题 100(23):LeetCode 206. 反转链表(Reverse Linked List)详解
java·算法·leetcode·链表
不会c嘎嘎5 天前
数据结构 --链表
数据结构·链表
南玖yy6 天前
C++ 类模板三参数深度解析:从链表迭代器看类型推导与实例化(为什么迭代器类模版使用三参数?实例化又会是怎样?)
开发语言·数据结构·c++·人工智能·windows·科技·链表