数据结构学习(七):双链表

一、双链表的定义

  1. 在线性表的链式存储结构中,没一个物理节点增加一个指向后继节点的指针域和一个指向前趋节点的指针域就叫双链表
  2. 双链表的优点
    A、从任一节点出发可以快速找到其前趋节点和后继节点
    B、从任一节点出发可以访问其他节点
  3. 一般来说,双链表的存储密度会低于单链表

二、双链表的类型定义(DLinkList)

     typedef struct DNode          //双链表节点类型
     {
           ElemType  data;
           struct DNode  *prior;        //指向前趋节点
           struct DNode  *next;        //指向后继节点
     }DLinkList;

三、双链表的建立

(1)头插法建表(链表的节点顺序与逻辑次序相反)

 void  CreateListF(DLinkList *&L,ElemType a[],int n)
    {
            DLinkList *s;
            int i;
            L=(DLinkList *)malloc(sizeof(DLinkList));       //创建头节点
            L->prior=L->next=NULL;                       //前后指针域域置为NULL
            for(i=0;i<n;i++)                                    //循环建立数据节点
            {
                 s=(DLinkList *)malloc(sizeof(DLinkList));
                 s->data=a[i];                  //创建数据节点 *s
                 s->next=L->next;           //将*s插在原开始节点之前,头节点之后
                 if(L->next!=NULL)         //若L存在数据节点,修改前趋指针
                         L->next->prior=s;
                 L->next=s;
                 s->prior=L;
            }
    }

(2)尾插法建表(链表的节点顺序与逻辑次序相同)

void  CreateListR(DLinkList *&L,ElemType a[],int n)
{
        DLinkList *s ,*r ;
        int i;
        L=(DLinkList *)malloc(sizeof(DLinkList));    //创建头节点
        r=L;                //r始终指向尾节点,开始时指向头节点
        for(i=0;i<n;i++)               //循环建立数据节点
        {
             s=(DLinkList *)malloc(sizeofD(LinkList));
             s->data=a[i];                  //创建数据节点 *s
             r->next=s; s->prior=r;                  //将*s插入 *r之后
             r=s;
        }
   r->next=NULL;     //尾节点next域置为NULL
}

四、线性表基本运算在双链表中的实现

      和单链表相比,双链表主要是插入和删除运算不同

(1)双链表的插入运算

 bool ListInsert(DLinkList *&L, int i,ElemType e)
       {
            int j=0;
            DLinkList   *p=L,*s ;   //p指向头节点,j设置为0
            while(j<i-1 && p!=NULL )   //查找第i-1个节点
            {
                 j++;
                p=p->next;
            }
           if( p ==NULL )   return  false;   //未找到第i-1个节点,返回false
           else                                        //找到第i-1个节点*p,在其后插入新节点*s
           {
                s=(DLinkList *)malloc(sizeof(DLinkList));
                s->data=e;            //创建新节点*s,其data域置为e
                s->next=p->next; //将*s插入到*p之后
                if(p->next!=NULL)         //若存在后继节点,则修改其前趋指针
                          p->naxt->prior=s;
                s->prior=p;  
                p->next=s;
                return  true;
           }
        }

(2)双链表的删除运算

   bool ListDelete(DLinkList *&L, int i,ElemType e)
   {
        int j=0;
        DLinkList   *p=L,*s ;   //p指向头节点,j设置为0
        while(j<i-1 && p!=NULL )   //查找第i-1个节点
        {
             j++;
            p=p->next;
        }
       if( p ==NULL )   return  false;   //未找到第i-1个节点,返回false
       else                                        //找到第i-1个节点*p,在其后插入新节点*s
       {
            q=p->next;            //q指向第i个节点
            if(q==NULL)         //若不存在第i个节点时返回false
                      return false;
            e=q->data;
            p->next=q->next;       //从双链表中删除*q节点
            if(p->next!=NULL)         //若存在后继节点,则修改其前趋指针
                      p->naxt->prior=p;
            free(q);              //释放*q节点
            return  true;
       }
    }
            
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值