10.38 2-路归并排序的另一策略是,先对待排序序列扫描一遍,找出并划分为若干个最大有序子列,将这些子列作为初始归并段。试写一个算法在链表结构上实现这一策略。

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 &lt1,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 &lt1,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 &lt1,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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值