当前位置: 首页 > news >正文

双向链表

单双链表的对比:  

 1.定义与结构
单向链表:是链表的一种,其特点是链表的链接方向是单向的,即每个节点只包含一个指向下一个节点的指针(或称为“链”)。访问链表中的元素需要从头部开始顺序读取。
双向链表:也叫双链表,同样是链表的一种,但每个数据节点中都有两个指针,一个指向直接后继,另一个指向直接前驱。这种结构使得双向链表中的节点可以方便地访问其前驱和后继节点。
2.操作复杂度
添加与删除操作:
单向链表在添加或删除节点时,通常需要遍历链表以找到操作位置的前一个节点,这导致操作的时间复杂度较高,特别是在链表较长时。
双向链表由于可以直接访问前驱节点,因此在添加或删除节点时,可以更快地定位到操作位置,减少遍历次数,提高操作效率。尤其是在链表头部或尾部频繁进行添加、删除操作时,双向链表的优势更为明显。
查找操作:
单向链表和双向链表在查找特定元素时的时间复杂度通常相同,都需要遍历链表中的每个节点进行比较。
3.空间复杂度
双向链表由于每个节点都需要额外存储一个指向前驱的指针,因此相比单向链表会占用更多的存储空间。在长度为n的链表中,双向链表需要多消耗n个指针的空间(每个节点一个)。
4.适用场景
单向链表:适用于对存储空间要求严格,且不需要频繁进行双向遍历的场景。
双向链表:适用于需要频繁进行双向遍历,或者对链表头部和尾部进行频繁添加、删除操作的场景。双向链表能够提供更灵活的操作方式,提高程序的运行效率。
5.总结
双向链表和单向链表各有优缺点,选择哪种链表结构取决于具体的应用场景和需求。在需要频繁进行双向遍历或头部、尾部操作较多的情况下,双向链表是更好的选择;而在对存储空间有严格要求,且不需要频繁进行双向遍历的场景下,单向链表则更为合适。

 双向链表的增删改查:

#include "link.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
//创建头
DLink_t* dlink_create()
{
    DLink_t* pdoulink = (DLink_t*)malloc(sizeof(DLink_t));
    if(NULL == pdoulink)
    {
        return NULL;
    }

    pdoulink->phead = NULL;
    pdoulink->clen = 0;
    pthread_mutex_init(&(pdoulink->mutex), NULL);
    return pdoulink;
}
//判空
int is_empty_dlink(DLink_t* pdoulink)
{
    return NULL == pdoulink->phead;
}
//头增
int push_dlink_head(DLink_t* pdoulink, DataType data)
{
    DLink_Node_t* pdnode = (DLink_Node_t*)malloc(sizeof(DLink_Node_t));
    if(NULL == pdnode)
    {
        return -1;
    }
    pdnode->data = data;
    pdnode->ppre = NULL;
    pdnode->pnext = NULL;

    if(is_empty_dlink(pdoulink))
    {
        pdoulink->phead = pdnode;    
    }
    else
    {
        pdnode->pnext = pdoulink->phead;
        pdoulink->phead->ppre = pdnode;
        pdoulink->phead = pdnode;
    }
    pdoulink->clen++;
    return 0;
}
//尾增
int push_dlink_tail(DLink_t* pdoulink, DataType data)
{
    if(is_empty_dlink(pdoulink))
    {
        push_dlink_head(pdoulink, data);
    }
    else
    {
        DLink_Node_t* pdnode = (DLink_Node_t*)malloc(sizeof(DLink_Node_t));
        if(NULL == pdnode)
        {
            return -1;
        }
        pdnode->data = data;
        pdnode->ppre = NULL;
        pdnode->pnext = NULL;

        DLink_Node_t* p = pdoulink->phead;
        while(p->pnext != NULL)
        {
            p = p->pnext;
        }
        
        p->pnext = pdnode;
        pdnode->ppre = p;

    }
    pdoulink->clen++;
    return 0;
}
//遍历
int print_dlink_all(DLink_t* pdoulink)
{
    if(is_empty_dlink(pdoulink))
    {
        printf("空\n");
    }
    else
    {
        DLink_Node_t* p = pdoulink->phead;
        while(p != NULL)
        {
            printf("id = %d name = %s score = %d\n", p->data.id, p->data.name, p->data.score);
            p = p->pnext;
        }
    }
    putchar('\n');
    return 0;
}
//头删
int pop_dlink_head(DLink_t* pdoulink)
{
    if(is_empty_dlink(pdoulink))
    {
        return -1;
    }
    else
    {
        DLink_Node_t* p = pdoulink->phead;
        pdoulink->phead = p->pnext;
        p->ppre = NULL;
        free(p);
    }
    pdoulink->clen--;
    return 0;
}
//尾删
int pop_dlink_tail(DLink_t* pdoulink)
{
    if(is_empty_dlink(pdoulink))
    {
        return -1;
    }
    else
    {
        DLink_Node_t* p = pdoulink->phead;
        while(p->pnext != NULL)
        {
            p = p->pnext;
        }

        p->ppre->pnext = NULL;
        free(p);
    }
    pdoulink->clen--;

    return 0;
}
//查找
DLink_Node_t* dfind_link(DLink_t* pdoulink, char *key)
{
    if(is_empty_dlink(pdoulink))
    {
        printf("空\n");
        return NULL;
    }
    DLink_Node_t* p = pdoulink->phead;

    while(p != NULL)
    {
        if(!strcmp(p->data.name , key))
        {
            return p;
        }
        p = p->pnext;
    }

    return NULL;
}
//修改
int change_dlink(DLink_t* pdoulink, DataType *key, int new_score)
{
    if(is_empty_dlink(pdoulink))
    {
        printf("空\n");
        return -1;
    }
    DLink_Node_t* find = dfind_link(pdoulink, key->name);
    find->data.score = new_score;
    return 0;
}
//清空
int delall_dlink(DLink_t* pdoulink)
{
    while(1)
    {
        if(is_empty_dlink(pdoulink))
        {
            free(pdoulink);
            return 0;
        }
        else
        {
            pop_dlink_head(pdoulink);
        }
    }
    return 0;
}

相关文章:

  • 浅谈DevOps在inBuilder低代码中的应用
  • yosys-f4pga-plugin编译教程
  • 新考纲下的PMP考试有多难?
  • Android使用addr2line分析Native Crash
  • 电脑里的文件删除了还能恢复吗?这些方法能帮你找回
  • DDD设计方法-3-仓储,封装持久化数据
  • 遍历所有文件夹,并把文件里所有的csv合并为一个dataframe
  • ES6基础----Map的使用
  • vue3.5更新内容
  • 爬虫常用模板
  • css画个熊猫
  • C语言:刷题笔记
  • MyCat
  • ant vue design日期组件date-picker自定义快捷选择日期封装
  • OpenXR Monado创建Swapchain和生成纹理
  • Verilog基础,原码,反码与补码的概念
  • 透明加密为什么是最佳选择,10款透明加密软件推荐
  • CGLIB 是什么
  • Linux驱动(四):Linux2.6字符设备驱动及GPIO子系统
  • [数据集][目标检测]鲜花检测数据集VOC+YOLO格式25215张106类别
  • 文天祥与“不直人间一唾轻”的元将唆都
  • 路边“僵尸车”被人以1450元卖了,嫌疑人被刑拘
  • 杭州一季度GDP为5715亿元,同比增长5.2%
  • 国务院任免国家工作人员:饶权任国家文物局局长
  • AI应用大盘点:谁暴涨?谁掉队?
  • 王文涛会见德国汽车工业协会主席穆勒