《数据结构和算法》之双向链表

1,双向链表的定义:


       双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表

       怎样理解双向链表,用生活中的一个例子来解释一下:最开始的火车是只有一个火车头的,当一辆火车从A->B->C->D->E->F->G->H->J->K->L这条路线进行行驶,假设或者运行到H站点要运送一批货物到G站点,只能通过H->J->K->L->A->B->C->D->F->G这个路线来进行,相当于是单向循环链表的形式。这个时候大家可以看到很费时和费力,严重的浪费时间和资源,这个时候人们就想了,如果火车可以倒着走那不就很方便吗,于是火车慢慢地开始有了两个火车头,这样可以往后走,直接后退一个站点,这样就可以轻松实现K->G的运输工作。这个小例子就类似于双向链表,但是真正意义上的双向链表跟这个又是有一点的区别,那么这个时候相对于单链表而言。双向链表就可以定义如下的结构体:

typedef struct DualNode
{
	ElemType data;
	struct DualNode *prior;  //前驱结点
	struct DualNode *next;   //后继结点 
}DualNode, *DuLinkList; 

        如下图1,双向链表的结点结构示意图以及空链表的结构示意图

                                                                 

                                                                                                                    图1 双向链表结点结构图

       在图1中可以看到,结点结构比之前的单链表多了一个结点,多一个头指针prior,存放着前驱结点的指针,当双向链表的两个结点都为空的时候则为空链表。

                        

                                                                                                                图2 非空的双向循环链表

    对于非空双向链表中的一个结点p,它的后继结点的前驱结点是什么? 当然就是它自己。

2,双向链表的插入操作

                                

                                                                                                         图3 可以看到双向循环链表的插入操作

              在图3中可以看到具体的操作步骤,具体代码实现如下:

                                                              

s->next = p;
s->prior = p->prior;
p->prior->next = s;
p->prior = s;


       这四步分别对应着图3中的四步操作,首先将s结点的后继指针指向p;接着将s的前驱结点赋值为p的前驱指针;p的前驱结点的后继结点赋值为s;最后将p的前驱结点赋值为s。

3,双向链表的删除操作

            

                                                                                                   图4   删除操作

         在图4中可以看到,直接将前一个元素的后继指针指向后一个元素的前驱结点,同时将后一个元素的前驱结点指向前一个元素的前驱结点。代码即为:

                              

p->prior->next = p->next;
p->next->prior = p->prior;
free(p);

4,与单链表的区别

       (1)从任意一个结点开始,可以查找链表中的其他任意结点。
  (2)既可以依照后继的方向(向后)遍历,也可以依照前驱的方向(向前)遍历。
  (3)每个指针域中都增加了一个存储指针的空间,降低了存储密度。
       (4)可以在当前结点前面或者后面插入,可以删除前趋和后继(包括结点自己)。 单链表只能在结点后面插入和删除。
  (5)双向链表通过增加一定的空间复杂度,降低了向前遍历的时间复杂度。

                                                                       

   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值