首页 > 数据结构 > 链表 阅读:57,774

双向链表

在双向链表中,结点除含有数据域外,还有两个链域,一个存储直接后继结点地址,一般称之为右链域;一个存储直接前驱结点地址,一般称之为左链域。

 

双向链表的存储结构定义如下:

typedef struct _dnode

{

       int data;

       struct _dnode *pre;//前向指针,指向结点左边的结点

       struct _dnode *next;//后继指针,指向结点右边的结点

}dnode, *pdnode;

双向链表的结构如下图所示:

 

2.3.1创建

在创建双向链表的时候,将一个新建的结点p,插入已知的双向链表中,有2种插入方法,如下图所示,一是直接插入头部,二是直接插入尾部。

 

//从头部插入方法创建双向链表:

dnode *create_dobulelist_head()

{

       dnode *h = NULL;

       while(1)

       {

              dnode *p=(dnode *)malloc(sizeof(dnode));

              if(p==NULL)

              {

                     return h;

              }

              memset(p,0,sizeof(p));

              printf("Please input your data\n");

              scanf_s("%d",&p->value);

              p->next=p->pre=NULL;

 

              if(h==NULL) //如果头结点指针为空,表明这是创建的第一个结点

              {

                     h=p;

              }

              else

              {

                     p->next = h;

                     h->pre=p;

                     h=p;

 

              }

              if(p->value==0)

              {

                     break;

              }

       }

       return h;

 

}

//从尾部插入创建双向链表:

dnode *create_dobulelist_tail()

{

       dnode *h = NULL;

       while(1)

       {

              dnode *p=(dnode *)malloc(sizeof(dnode));

              if(p==NULL)

              {

                     return h;

              }

              memset(p,0,sizeof(p));

              printf("Please input your data\n");

              scanf_s("%d",&p->value);

              p->next=p->pre=NULL;

 

              if(h==NULL)//如果头结点指针为空,表明这是创建的第一个结点

              {

                     h=p;

              }

              else

              {

                     dnode *q=h;

                     while(q->next)//需要先从头结点开始遍历到尾结点

                     {

                            q=q->next;

                     }

                     q->next = p;

                     p->pre=q;

                     p->next = NULL;

 

              }

              if(p->value==0)//创建循环退出

              {

                     break;

              }

       }

       return h;

 

}

2.3.2插入

如图所示,将一个结点p插入到双向链表q的后面(注意,照着图分析最有效,不要死记硬背插入代码):

2.3.3删除

双向链表中,将一个结点p从双向链表中删除方法:

2.3.4遍历

双向链表的遍历,和单向链表的遍历方法差不多:

void traverse_dlist_next(dnode *h)

{

       dnode *p=h;

       while(p)

       {

              printf("%d ",p->value);

              p=p->next;

       }

       printf("\n");

 

}

2.3.5销毁

双向链表的销毁,与单向链表的销毁算法类似:

void destroy_dlist(dnode *h)

{

       dnode *p =h;

       while(p)

       {

              dnode *q=p;

              p=p->next;

              free(q);

       }

}

周哥教IT,分享编程知识,提高编程技能,程序员的充电站。跟着周哥一起学习,每天都有进步。

通俗易懂,深入浅出,一篇文章只讲一个知识点。

当你决定关注「周哥教IT」,你已然超越了90%的程序员!

IT黄埔-周哥教IT技术交流QQ群:213774841,期待您的加入!

二维码
微信扫描二维码关注