为一趟归并段的段长
for(p=L->next,e2=p;p->next;p=e2)
{
for(i=1,q=p;i<=l&&q->next;i++,q=q->next);
e1=q;
for(i=1;i<=l&&q->next;i++,q=q->next);
e2=q;//求出两个待归并子序列的尾指针
if(e1!
=e2)LinkedList_Merge(L,p,e1,e2);//归并
}
}//LinkedList_Merge_Sort1
voidLinkedList_Merge(LinkedList&L,LNode*p,LNode*e1,LNode*e2)//对链表上的子序列进行归并,第一个子序列是从p->next到e1,第二个是从e1->next到e2
{
q=p->next;r=e1->next;//q和r为两个子序列的起始位置
while(q!
=e1->next&&r!
=e2->next)
{
if(q->datadata)//选择关键字较小的那个结点接在p的后面
{
p->
next=q;p=q;
q=q->next;
}
else
{
p->next=r;p=r;
r=r->next;
}
}//while
while(q!
=e1->next)//接上剩余部分
{
p->next=q;p=q;
q=q->next;
}
while(r!
=e2->next)
{
p->next=r;p=r;
r=r->next;
}
}//LinkedList_Merge
10.38
voidLinkedList_Merge_Sort2(LinkedList&L)//初始归并段为最大有序子序列的归并排序,采用链表存储结构
{
LNode*end[MAXSIZE];//设立一个数组来存储各有序子序列的尾指针
for(p=L->next->next,i=0;p;p=p->next)//求各有序子序列的尾指针
if(!
p->next||p->data>p->next->data)end[i++]=p;
while(end[0]->next)//当不止一个子序列时进行两两归并
{
j=0;k=0;//j:
当前子序列尾指针存储位置;k:
归并后的子序列尾指针存储位置
for(p=L->next,e2=p;p->next;p=e2)//两两归并所有子序列
{
e1=end[j];e2=end[j+1];//确定两个子序列
if(e1->next)LinkedList_Merge(L,p,e1,e2);//归并
end[k++]=e2;//用新序列的尾指针取代原来的尾指针
j+=2;//转到后面两个子序列
}
}//while
}//LinkedList_Merge_Sort2
voidLinkedList_Merge(LinkedList&L,LNode*p,LNode*e1,LNode*e2)//对链表上的子序列进行归并,第一个子序列是从p->next到e1,第二个是从e1->next到e2
{
q=p->next;r=e1->next;
while(q!
=e1->next&&r!
=e2->next)
{
if(q->datadata)
{
p->next=q;p=q;
q=q->next;
}
else
{
p->next=r;p=r;
r=r->next;
}
}//while
while(q!
=e1->next)
{
p->next=q;p=q;
q=q->next;
}
while(r!
=e2->next)
{
p->
next=r;p=r;
r=r->next;
}
}//LinkedList_Merge,与上一题完全相同
10.39
voidSL_Merge(inta[],intl1,intl2)//把长度分别为l1,l2且l1^2<(l1+l2)的两个有序子序列归并为有序序列
{
start1=0;start2=l1;//分别表示序列1和序列2的剩余未归并部分的起始位置
for(i=0;i {
for(j=start2;j k=j-start2;//k为要向右循环移动的位数
RSh(a,start1,j-1,k);//将a[start1]到a[j-1]之间的子序列