10.38 2-路归并排序的另一策略是,先对待排序序列扫描一遍,找出并划分为若干个最大有序子列,将这些子列作为初始归并段。试写一个算法在链表结构上实现这一策略。
#include<stdio.h>
#include<stdlib.h>
#define maxsize 100
typedef struct{
int r[maxsize];
int length;
}SqList;
typedef struct LNode{
int data;
struct LNode *next;
}LNode;
typedef LNode* LinkList;
//在order[]中记录每个最大有序子列的第一个结点
void scan(LinkList L,int n,LNode* order[],int &k){
LNode *p;
k=0;
int i;
for(i=0;i<n;i++){
order[i]=NULL;
}
p=L->next;
while(p){
order[k]=p;k++;
while(p->next&&p->data<p->next->data)
p=p->next;
p=p->next;
}
printf("scan:");
for(i=0;i<k;i++){
printf("%d ",order[i]->data);
}putchar(10);
}
//合并第i和第j个子列,k为order数组长度
void merge(LinkList <1,LNode* order[],int i,int j,int k,int length){
LinkList lt2;
lt2=(LNode*)malloc(sizeof(LNode));lt2->next=NULL;
LNode *p,*q,*post1,*post2,*r,*t;
p=order[i];q=order[j];post1=q;
if(j+length<k) post2=order[j+length];
else post2=NULL;
r=lt2;
while(p!=post1&&q!=post2){ //记录在lt2中
t=(LNode*)malloc(sizeof(LNode));t->next=NULL;
if(p->data<q->data){
t->data=p->data;
r->next=t;r=t;
p=p->next;
}else{
t->data=q->data;
r->next=t;r=t;
q=q->next;
}
}
while(p!=post1){
t=(LNode*)malloc(sizeof(LNode));t->next=NULL;
t->data=p->data;
r->next=t;r=t;
p=p->next;
}
while(q!=post2){
t=(LNode*)malloc(sizeof(LNode));t->next=NULL;
t->data=q->data;
r->next=t;r=t;
q=q->next;
}
LNode *w,*e;
if(i==0) lt1->next=lt2->next; //用lt2替换lt1中原来的子列
else{
e=lt1->next;
while(e->next->data!=order[i]->data) e=e->next;
e->next=lt2->next;
}
if(j<k-1){
r->next=order[j+length];
}
w=lt1->next; //更新order[],只需更新本次排序中的第一个子列
while(w->data!=lt2->next->data) w=w->next;
order[i]=w;
printf("tl1:");
for(w=lt1->next;w;w=w->next){
printf("%d ",w->data);
}putchar(10);
}
void MergePass(LinkList <1,LNode* order[],int k,int length){
int i=0;
for(i=0;i+2*length-1<k;i=i+2*length){
merge(lt1,order,i,i+length,k,length);
}
if(i<k){
if(i+length>=k){
}else{
merge(lt1,order,i,i+length,k,length);
}
}
}
void MergeSort(LinkList <1,int n){
int k=0,i;
LNode* order[n];
LNode *p;
scan(lt1,n,order,k);
int len;
for(len=1;len<n;len=len*2){
MergePass(lt1,order,k,len);
}
}
int main(){
SqList L;
int i;
scanf("%d",&L.length);
for(i=1;i<=L.length;i++){
scanf("%d",&L.r[i]);
}
LinkList lt;
LNode *r;
lt=(LNode*)malloc(sizeof(LNode));
r=lt;
for(i=1;i<=L.length;i++){
LNode *p=(LNode*)malloc(sizeof(LNode));
p->data=L.r[i];
p->next=NULL;
r->next=p;
r=r->next;
}
MergeSort(lt,L.length);
return 0;
}
输入: 长度为12
12 49 38 65 97 76 13 27 99 55 44 12 3
输出:
scan:49 38 76 13 55 44 12 3
tl1:38 49 65 97 76 13 27 99 55 44 12 3
tl1:38 49 65 97 13 27 76 99 55 44 12 3
tl1:38 49 65 97 13 27 76 99 44 55 12 3
tl1:38 49 65 97 13 27 76 99 44 55 3 12
tl1:13 27 38 49 65 76 97 99 44 55 3 12
tl1:13 27 38 49 65 76 97 99 3 12 44 55
tl1:3 12 13 27 38 44 49 55 65 76 97 99