双链表 、循环链表

一、双链表 
   对于双链表,采用类似于单链表的类型定义,其DLinkList类型的定义如下:
    typedef struct DNode       //声明双链表节点类型
   { ElemType data;
      struct DNode *prior;    //指向前驱节点
      struct DNode *next;     //指向后继节点

   } DLinkList;

1.建立双联表

1)头插法

void CreateListF(DLinkList *&L,ElemType a[],int n)
//头插法建立双链表:由含有n个元素的数组a创建带头节点的双链表L
{ 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)
//尾插法建立双链表:由含有n个元素的数组a创建带头节点的双链表L
{  DLinkList *s,*r;
   int i;
   L=(DLinkList *)malloc(sizeof(DLinkList));//创建头节点
   r=L; //r始终指向尾节点,开始时指向头节点
   for (i=0;i<n;i++) //循环建立数据节点
   {  s=(DLinkList *)malloc(sizeof(DLinkList));
s->data=a[i]; //创建数据节点*s
r->next=s;s->prior=r; //将*s插入*r之后
r=s; //r指向尾节点
   }
   r->next=NULL; //尾节点next域置为NULL

}

2.插入节点

int 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) //未找到第i-1个节点,返回false
return -1;
   else //找到第i-1个节点*p,在其后插入新节点*s
   { s=(DLinkList *)malloc(sizeof(DLinkList));
s->data=e; //创建新节点*s
s->next=p->next; //在*p之后插入*s节点
if (p->next!=NULL)//若存在后继节点,修改其前驱指针
   p->next->prior=s;
s->prior=p;
p->next=s;
return 1;
   }
}

3.删除节点

int ListDelete(DLinkList *&L,int i,ElemType &e)
{  int j=0; DLinkList *p=L,*q;  //p指向头节点,j设置为0
   while (j<i-1 && p!=NULL)   //查找第i-1个节点
   { j++;
p=p->next;
   }
   if (p==NULL)    //未找到第i-1个节点
return -1;
   else    //找到第i-1个节点*p
   { 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->next->prior=p;
free(q);     //释放*q节点
return 1;
   }

}

二、循环链表

循环链表是另一种形式的链式存储结构。它的特点是表中最后一个节点的指针域不再是空,而是指向表头节点,整个链表形成一个环。由此从表中任一节点出发均可找到链表中其他节点。 

例1,编写出判断带头节点的双向循环链表L是否对称相等的算法。

解:p从左向右扫描L,q从右向左扫描L,若对应数据节点的data域不相等,则退出循环,否则继续比较,直到p与q相等或p的下一个节点为*q为止。

int Equeal(DLinkList *L)
{  int same=1;
   DLinkList *p=L->next; //p指向第一个数据节点
   DLinkList *q=L->prior;     //q指向最后数据节点
   while (same==1)
      if (p->data!=q->data)
         same=0;
else  
       {     
    if (p==q) break; //数据节点为奇数的情况
    q=q->prior;
    if (p==q) break; //数据节点为偶数的情况
          p=p->next;
}
   return same;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值