一日三题
假设有两个按元素值递增次序排列的线性表,均以单链表形式存储。请编写算法将这两个单链表归为一个按元素值递减次序排列的单链表,并要求利用原来两个单链表的结点存放归并后的单链表
解答:
算法思想:两个链表已经按元素值递增次序排序,将其合并时,均从第一个结点起进行比较,将小的结点链入链表中,同时后移工作指针。该问题要求结果链表按元素递减次序排列,故新链表的建立应该采用头插法。比较结束后,可能会有一个链表非空,此时用头插法将剩下的结点依次插入新链表中即可。
下面展示一些 代码
。
void MergeList(LinkList &La, LinkList &Lb)
//合并两个递增有序链表(带头结点),并使合并后的链表递减排列
{
LNode *r, *pa=La->next, *pb=Lb->next;//分别是表La和Lb的工作指针
La->next=NULL; //La作为结果链表的头指针,先将结果链表初始化为空
while(pa&&pb) //当两链表均不为空时,循环
if(pa->data<=pb->data)
{
r=pa->next; //r暂存pa的 后继结点指针
pa->next=La->next;
La->next=pa; //将pa结点链于结果表中,同时逆置(头插法)
pa=r; //恢复pa为当前待比较结点
}
else{
r=pb->next; //r暂存pb的后继结点指针
pb->next=La->next; //
La->next=pb; //将pb结点链于结果表中,同时逆置(头插法)
pb=r; //恢复pb为当前待比较结点
}
if(pa)
pb=pa; //通常情况下会剩一个链表非空,处理剩下的部分
while(pb) //处理剩下的非空链表
{
r=pb->next; //依次插入到La中(头插法)
pb->next = La->next;
La->next= pb;
pb = r;
}
free(Lb);
}
2.设A和B是两个单链表(带头结点),其中元素递增有序。设计一个算法从A和B中公众元素产生单链表C,要求不破坏A,B的结点。
解:
算法思想:表A,B都有序,可从第一个元素起依次比较A、B两表的元素,若元素值不等,则值小的指针往后移,若元素值相等,则可创建一个值等于两个结点的元素值的新结点,使用尾插法插入到新的链表中,并将两个原表指针后移一位,直到其中一个链表遍历到表尾。
下面展示一些 内联代码片
。
void Get_Common(LinkList A,LinkList B)
{
LNode *p = A->next, *q = B->next, *r, *s;
LinkList C = (LinkList)malloc(sizeof(LNode)); //建立表C
r= C; //r始终指向C的尾结点
while(p!=NULL&&q!=NULL){ //循环跳出条件
if(p->data<q->data)
p=p->next; //若A的当前元素较小,后移指针
else if(p->data>q->data)
q=q->next; //若B的当前元素较小,后移指针
else{ //找到公共元素结点
s= (LNode*)malloc(sizeof(LNode));
s->data = p ->data; //复制产生结点*s
r->next = s; //将*s链接到C上(尾插法)
r= s;
p = p ->next; //表A和B继续向后扫描
q= 1->next;
}
}
r->next = NULL; //置C尾结点指针为空
}
3.设计一个算法用于判断带头结点的循环双链表是否对称
解答:
算法思想:让p从左向右扫面,q从右向左扫描,知道它们指向同一结点(p==q, 当循环双链表中结点个数为基数时)或相邻(p->next = q 或 q->prior = p,当循环双链表中结点个数为偶数时)为止,若它们所指结点值相同,则继续进行下取,否则返回0。若比较全部相等,则返回1.
下面展示一些 内联代码片
。
int Symmetry(DLinkList L)
//本算法从两头扫描循环双链表,以判断链表是否对称
{
DNode *p = L->next, *q = L -> prior ; //两头工作指针
while(p!=q&&q->next!=p) //循环跳出条件
if(p->data == q->data) //所指结点指相同则继续比较
{
p= p->next;
q=q->prior;
}
else //否则返回0
return 0;
return 1; //比较结束后返回1
}