设单链表A和B都非递减有序,试设计算法,将A和B合并成非递减有序的单链表C,并要求利用原表A和B的结点空间构成表C
- 采用尾插法
(由于A、B非递减,C也要求非递减,顺序一致)
非递减排序算法(本质是选择排序)
void SORT(linklist *head)
{
linklist *p,*q;
int t;
for(p=head->next;p;p=p->next)
{
for(q=p->next;q;q=q->next)
{
if(p->data>q->data)
{
t=q->data;
q->data=p->data;
p->data=t;
}
}
}
}
这是老师给出的算法,个人觉得优点小问题
- 关于循环结束的条件
- 最后结束时p==NULL
- 倒数第一次中p->next==NULL(相当于p指向了最后一个结点),这样q=p->next == NULL就不会执行;
- 相当于多判断一次
- 关于值交换的问题
- 每次判断都进行值的交换显然开销过大
- 可以在内层循环结束后,再进行判断
我将其优化,可能会存在问题,请大家帮忙改正
void SORT(linklist *head)
{
linklist *p,*q;
linklist *s;
int t;
for(p=head->next;p->next!=NULL;p=p->next)
{
k=p->data;
for(q=p->next;q;q=q->next)
{
if(k>q->data)
{
k=q->data;
s=q;
}
}
if(p->data!=k)
{
t=p->data;
s->data=p->data;
p->data=t;
}
}
}
两个单链表合并过程
- 单链表A的头结点作为合并表C的头结点
- pc指向当前C的最后一个结点,pc的初值指向C的头结点
C=A,pc=C; - 当两者都没有到达尾部的时候,逐一取出pa和pb的值进行比较,插入较小的值插入表C的尾结点之后
while(pa&&pb)
{
if(pa->data<pb->data)
{
pc->next=pa;
pc=pa;
pa=pa->next;
}
else
{
pc->next=pb;
pc=pb;
pb=pb->next;
}
}
- 由一个到达尾部则把另一个其余的直接链接过去
合并代码
linklist * COMB(linklist *a,linklist *b)
{
linklist *c;
linklist *pa,*pb,*pc;
pa=a->head;
pb=b->head;
c=a;
pc=c;
while(pa&&pb)
{
if(pa->data < pb->data)
{
pc->next=pa;
pc=pa;
pa=pa->next;
}
else
{
pc->next=pb;
pc=pb;
pb=pb->next;
}
}
if(pa)
{
pc->next=pa;
}
if(pb)
{
pc->next=pb;
}
//释放掉B链表的头结点
free(b);
return c;
}