双向链表学习笔记

                  利用双向链表可以避免单链表的缺点,单链表的缺点就是查找指针p指向的节点,必须从指针p开始遍历整个链表一遍,时间复杂度为O(n)。

                双向链表的每个节点有两个指针一个指针指向前驱节点,另一个指向后继节点
  在双向循环链表中每个节点包括3个域,data域,prior域,next域。双向链表也分为带头节点和不带头节点
  带头结点使某些操作更加方便,另外双向链表也有循环结构,成为双向循环链表,带头节点的双向循环链表,双向
  循环链表为空的情况,判断带头节点的双向循环链表为空的条件是:head->prior == head 或者head->next == head.
  在双向循环链表中,因为每个节点既有前驱节点的指针域又有后继节点的指针域,所以查找节点非常方便。

 

双向链表的插入和删除跟单链表跟单链表不同,其他没有什么差异,所以在这里就直接讲一下插入和删除。

插入操作:就是要在带头的节点的双向循环链表中的第i个位置插入一个元素的值为E的节点
  ,插入成功返回1,否则返回0。

  算法思想:首先找到第i个节点,用p指向该节点,再申请一个新节点由s指向该节点将e放入到数据域然后开始修改
  p和s指向节点指针域,修改s的prior,使其指向p的直接前驱结点。s->prior = p->prior;
  将p的直接前驱结点的next域指向s指向的结点即p->prior->next = s;修改s的next指针域使其指向p指向的结点即s->next = p;
  修改p的prior域,使其指向s 的指向的结点,即p->prior = s;

代码一下:

 int InsertDList(DListLink head,int i,DataType e)
  {
    DListLink *p,*s;
 int j;
 p = head->next;
 j=0;
 while(p != head && j<i)
 {
    p=p->next;
    j++;
 
 }
 if(j != i)
 {
    printf("插入位置不正确");
    return 0;
 }
 s = (DListNode *)malloc(sizeof(DListNode));
 if(!s)
 return -1;
 s->data = e;
 s->prior = p->prior;
 p->prior->next = s;
 s->next = p;
 p->prior = s;
 return 1;
   
 
 
  
  }

 

双向循环链表的删除的操作--就是将带头节点的双向循环链表中的第i节点删除。删除成功返回1,否则返回0.
思路:
1:首先找到第i个结点,用p指向该结点,然后开始修改p指向的结果的直接前驱和直接后继结点的指针域,从而
将p链表断开,断开分为2步:
一:p->prior-next = p->next;
二:p->next->prior = p->prior;
代码如下:

int DeletDList(DListLink head,int i,DataType *e)
{
 DListLink *p;
 int j;
 p = head->next;
 j=0;
 while(p != head && j<i)
 {
    p=p->next;
    j++;
 
 }
 if(j != i)
 {
    printf("删除位置不正确");
    return 0;
 }
 p->prior->next = p->next;
 p->next->prior = p->prior;
 free(p);
 return -1;


}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值