双向链表的创立与相关操作

双向链表,顾名思义,就是每个数据结点含有两个指针,分别指向前驱结点和后继结点。

双向链表图示:

这里写图片描述
在理解单链表的创立后,结合双链表的特点,很容易写出其创建。首先,双链表比单链表多了一个前驱指针pre,因此结构体的建立是这样的(以之存储int类型的num为例)

typedef struct node{
    int num;
    struct node *pre;//前驱节点
    struct node *next;//后继节点
}NODE;

我们以创建带有头节点的双链表为例进行说明:
初始状态下,我们定义结构体指针head,且head内不存放数值,这里一定要注意为head开辟内存空间,因为最后我们需要获取head所指向的地址,它不能是指向一个随机位置。而后head变为旧的节点。

    head=(NODE *)malloc(sizeof(NODE));
    head->pre=NULL;
    head->next=NULL; 
    pend=head;

在循环内,为了满足互相指向的关系,首先,新的指针的前驱节点应该指向旧的地址,然后新的指针的后继节点当然指向为空,代码:

pnew->pre=pend;
pnew->num=n;
pnew->next=NULL;

此时两块内存的关系变成了:

这里写图片描述
观察对比最上面的描述图发现,新节点的前驱节点已经有了指向,而上个节点的后继节点还没指向下一块内存,因此我们还需加入一句:pend->next=pnew,然后让新节点更替为旧节点即可。

完整的创建:

NODE *createlink()
{
    NODE *head,*pnew,*pend;
    int n;
    head=(NODE *)malloc(sizeof(NODE));
    head->pre=NULL;
    head->next=NULL; 
    pend=head;
    scanf("%d",&n);
    while(n>=0)
    {
        pnew=(NODE *)malloc(sizeof(NODE ));
        pnew->pre=pend;
        pnew->next=NULL;
        pnew->num=n;
        pend->next=pnew;
        pend=pnew;
        scanf("%d",&n);
    }
    return head;
}

另外,总结一下数组、单链表、双链表的区别与相关问题:
参考了一篇别人的文章:https://blog.csdn.net/kangxidagege/article/details/80211225
数组与单链表的的区别:
数组静态分配内存,链表动态分配内存;数组在内存中连续,链表不连续;数组利用下标定位,时间复杂度为O(1),链表定位元素时间复杂度O(n);数组插入或删除元素的时间复杂度O(n),链表的时间复杂度O(1)。

优缺点方面:

数组的优点

  • 随机访问性强(通过下标进行快速定位)
  • 查找速度快

数组的缺点

  • 插入和删除效率低(插入和删除需要移动数据)
  • 可能浪费内存(因为是连续的,所以每次申请数组之前必须规定数组的大小,如果大小不合理,则可能会浪费内存)
  • 内存空间要求高,必须有足够的连续内存空间。
  • 数组大小固定,不能动态拓展

链表的优点:

  • 插入删除速度快(因为有next指针指向其下一个节点,通过改变指针的指向可以方便的增加删除元素)
  • 内存利用率高,不会浪费内存(可以使用内存中细小的不连续空间(大于node节点的大小),并且在需要空间的时候才创建空间)
  • 大小没有固定,拓展很灵活。

链表的缺点:

  • 不能随机查找,必须从第一个开始遍历,查找效率低

另:

查找方面,基于双链表的特点,可以使用二分法加快搜索速率,但是为什么市场上使用单链表要多于双向链表呢?
从存储结构来看,每个双链表的节点要比单链表的节点多一个指针,而长度为n就需要 n*length(这个指针的length在32位系统中是4字节,在64位系统中是8个字节) 的空间,这在一些追求时间效率不高应用下并不适应,因为它占用空间大于单链表所占用的空间;这时设计者就会采用以时间换空间的做法,这时一种工程总体上的衡量。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值