在其他情况下均称A>B。
试编写一个比较A和B的算法,当AB时分别输出-1、
0或1。
intcomp(LA,LB)//判断2个表的大小
{
Lla,lb;
if(A==NULL||A->next==NULL||B==NULL||B->next==NULL)
exit(0);
la=A;
lb=B;
la=A->next;
lb=B->next;
while(la->i==lb->i)
{
la=la->next;
lb=lb->next;
if(la==NULL&&lb!
=NULL)
{
return-1;
}
if(lb==NULL&&la!
=NULL)
{
return1;
}
if(NULL==la&NULL==lb)
return0;
}
if(la==A->next&&lb==B->next)
return1;
elseif(la->ii)
return-1;
elsereturn1;
}
【例3.6】假设有两个按元素值递增有序排列的单链表A和B,编写一个算法将A和B
归并成一个按元素值递增有序排列的单链表C(相同值的元素只归并一次),并要求利用原单
链表(A和B)的节点空间存放单链表C。
LCombineList(Ll1,Ll2)//将两个按由小到大递增的链表进行排序
{
Lp1,p2,p3,l3;
if(l1==NULL||l1->next==NULL||l2==NULL||l2->next==NULL)
exit(0);
l3=(L)malloc(sizeof(List));
if(NULL==l3)
exit(0);
p1=l1->next;
p2=l2->next;
p3=l3;
while(p1!
=NULL&&p2!
=NULL)
{
if(p1->i>p2->i)
{
p3->next=p2;
p3=p2;
if(p2->next==NULL)
{
p2=p2->next;
break;
}else
p2=p2->next;
}
if(p1->ii)
{
p3->next=p1;
p3=p1;
if(p1->next==NULL)
{
p1=p1->next;
break;
}else
p1=p1->next;
}
if(p1->i==p2->i)
{
p3->next=p1;
p3=p1;
if(NULL==p1->next||NULL==p2->next)
{
p1=p1->next;
p2=p2->next;
break;
}else
p1=p1->next;
p2=p2->next;
}
}
if(p1!
=NULL)
{
p3->next=p1;
}
if(p2!
=NULL)
{
p3->next=p2;
}
returnl3;
}
【例3.10】设计循环单链表结构并实现循环单链表的基本操作。
【解】不带哨兵节点的循环单链表结构如图3.6所示。
其中h为头节点指针,亦简称
为头指针。
图3.6不带哨兵节点的循环单链表结构
实现本题功能的clink.cpp文件如下(后面的有关循环单链表的算法设计都使用其中的
函数,其中的循环单链表都是不带哨兵节点的循环单链表):
#include
#include
typedefintelemtype;//定义数据域的类型
typedefstructlinknode//定义节点类型
{
elemtypedata;
structlinknode*next;
}nodetype;
nodetype*cyccreate()
//创建循环单链表,用户输入各节点data域之值,0表示输入结束
{
elemtyped;
nodetype*h=NULL,*s,*t=NULL;
inti=1;
cout<<"建立一个循环单链表"<while
(1)
{
cout<<"输入第"<
";
cin>>d;
if(d==0)break;//以0表示输入结束
if(i==1)//建立第一个节点
{
h=(nodetype*)malloc(sizeof(nodetype));
h->data=d;h->next=NULL;t=h;
}
else//建立其余节点
{
s=(nodetype*)malloc(sizeof(nodetype));
s->data=d;s->next=NULL;t->next=s;
t=s;//t始终指向生成的循环单链表的最后一个节点
}
i++;
}
if(t!
=NULL)t->next=h;
//将最后一不为NULL的节点的next置为h
returnh;
}
voidcycdisp(nodetype*h)
//输出由h指向的循环单链表的所有data域之值
{
nodetype*p=h;
cout<<"输出一个循环单链表:
"<if(p==NULL)
{
cout<<"空表"<}
while(p->next!
=h)
{
cout<data<<"";p=p->next;
}
cout<data<<""<}
intcyclen(nodetype*h)//返回循环单链表的长度
{
inti=1;
nodetype*p=h;
if(p==NULL)return0;
while(p->next!
=h)
{
p=p->next;i++;
}
returni;
}
nodetype*cycfind(nodetype*h,inti)
//返回第i个节点的指针
{
nodetype*p=h;
intj=1;
if(i>cyclen(h)||i<=0)returnNULL;//i值上溢或下溢
else
{
if(i==1)returnp;//i=1时返回头指针
while(p->next!
=h&&j
{
j++;p=p->next;
}
returnp;
}
}
nodetype*cycins(nodetype*h,inti,elemtypex)
//在循环单链表head中第i个节点(i>=0)之后插入一个data域为x的节点
{
nodetype*p,*s,*r;
s=(nodetype*)malloc(sizeof(nodetype));//创建节点s
s->data=x;s->next=NULL;
if(i==0)//i=0:
s作为该循环单链表的第一个节点
{
r=h;
while(r->next!
=h)r=r->next;//r为最后节点的指针
s->next=h;h=s;r->next=h;//修改r的next域
}
else
{
p=cycfind(h,i);//查找第i个节点,并由p指向该节点
if(p!
=NULL)//将s插入到p之后
{
s->next=p->next;p->next=s;
}
elsecout<<"输入的i值不正确"<}
returnh;
}
nodetype*cycdel(nodetype*h,inti)//删除第i个节点
{
nodetype*p=h,*s,*r;
intj=1;
if(i==1)//删除第1个节点
{
r=h;
while(r->next!
=h)r=r->next;//r为最后节点的指针
h=h->next;r->next=h;//重置r的next域
free(p);
}
else
{
p=cycfind(h,i-1);//查找第i-1个节点,并由p指向该节点
if(p!
=NULL&&p->next!
=h)//若存在要删除的节点
{
s=p->next;//s指向要删除的节点
p->next=s->next;free(s);
}
elsecout<<"输入的i值不正确"<}
returnh;
}
voidcycdispose(nodetype*h)//释放循环单链表的所有节点占用的空间
{
nodetype*pa=h,*pb;
if(pa!
=NULL)
{
pb=pa->next;
if(pb==h)//只有一个节点的情况
free(pa);
else
{
while(pb->next!
=h)//有两个及以上节点的情况
{
free(pa);pa=pb;pb=pb->next;
}
free(pa);
}
}
}
【例3.11】假设在长度大于1的循环单链表中,既无头节点也无头指针,p为指向该
链表中某个节点的指针。
设计一个算法删除该节点的前驱节点。
【解】本题利用循环单链表的特点,通过p指针循环找到其前驱节点q及q的前驱节点
r,然后将其删除。
实现本题功能的程序如下:
#include"clink.cpp"
nodetype*delprev(nodetype*p)
{
nodetype*r=p,*q=r->next;
while(q->next!
=p)//查找p节点的前驱节点q,r指向q的前驱节点
{
r=r->next;q=r->next;
}
r->next=p;//删除