合并排序

      合并排序是成功应用分治技术的一个完美例子。对于一个需要排序的数组A[0..n-1],合并排序把她一分为二:A[0..[n/2]-1]和A[[n/2]..n-1],并对每个子数组递归排序然后把这两个排好序的子数组合并为一个有序数组。

编译器为  vc++6.0

代码为

#include<stdio.h>
#include<stdlib.h>
void merge(int* num,int *numB,int lenB,int *numC,int lenC);
void Mergesort(int* num,int len);
int main()
{
   FILE * fpRead;
   FILE * fpWrite;
   char * pchBuf;
   char  tmp[5];
   int Len;
   int i,j=0,k=0,nLen=0;
   int num[200];
   fpRead=fopen("bs-2.txt","r");    //以只读打开文件
   fseek(fpRead,0,SEEK_END);            //将文件指针移到结尾
   Len=ftell(fpRead);                   //计算文件长度
   rewind(fpRead);                      //将文件指针移到开头
   pchBuf=(char*)malloc(sizeof(char)*Len+1);    //在堆里开空间存放文件的内容
    if(!pchBuf)                             //如果没有分配退出
	{
	    printf("内存不够!\n");
		exit(0);
	}
    Len = fread(pchBuf,sizeof(char),Len,fpRead);  //将文件内容放入空间中,并自动调整长度
    fclose(fpRead);                              //关闭文件
	pchBuf[Len] = '\0';                      //将字符长结尾附零
	for (i=0;i<=Len;i++)                     
	{
	
		tmp[j++]=*(pchBuf+i);                //找到字符串开头
		if (*(pchBuf+i)==',' ||*(pchBuf+i)=='\0' )  //判断是否遇到逗号和结尾
		{    
			tmp[j] = '\0';                       //将子字符串附零
	        nLen++;
		  	num[k++]=atoi(tmp);                    //将字符串转化为整形
			j=0;                                  //查找下一个字符串
		}
	}                                              
     Mergesort(num,nLen);                       //调用合并排序
     fpWrite=fopen("output.txt","w");               //打开要写入的文件
	 for(i=0;i<nLen;i++)
	 {
	    fprintf(fpWrite,"%d,",num[i]);           //将排好序的数组写入文件
		if(i%10==9)                              //每十个换一行
		fprintf(fpWrite,"\n");
	 }
	 fclose(fpWrite);                           //关闭文件
	 return 0;
}
//合并算法
//输入:待排序的数组,数组的长度
//输出:排好序的数组
void Mergesort(int* num,int len)
{
	  int i;
	  int n=len/2;                   //子串1的长度
	  int m=len-n;                    //子串2的长度
      int* numB;               
	  int* numC;
	  numB=(int *)malloc(n*sizeof(int));  //子串1的存储空间
      numC=(int *)malloc(m*sizeof(int));  //子串2的存储空间
	if(len>1)                             //判断是否分到了最后
	{
		for(i=0;i<n;i++)                   //将字符串的前部分拷贝到numB
		{ 
		    numB[i]=num[i];
		}
		for(i=0;i<m;i++)                 //将字符串的后部分拷贝到numC
		{
		    numC[i]=num[n];
			n++;
		}
		   n=len/2;                       //因前面拷贝使赋值改变,故重新赋值
			Mergesort(numB,n);            //递归的调用
	        Mergesort(numC,m);
		    merge(num,numB,n,numC,m);       //调用合并程序
	}


}

void merge(int *num,int* numB,int lenB,int* numC,int lenC)
{
	int i=0;
	int j=0;
	int k=0;
    while(i<lenB && j<lenC)     //判断是否到了最后
	{
	   if(numB[i]<=numC[j])      //将较小值放进
	   {
         num[k]=numB[i];
		 i++;
	   }else
	   {
	      num[k]=numC[j];
		  j++;
	   }
	   k++;
	}
	if(i==lenB)                 //如果有一个到了最后将后面排好序的直接拷贝过去
	{
	    	for(j;j<lenC;j++)
			{
		       num[k]=numC[j];
			   k++;
			}
	}else
	{
	    for(i;i<lenB;i++)
			{
		       num[k]=numB[i];
			   k++;
			}
	}
}
读入文件为

bx-2.txt

132,133,134,11,12,139,140,62,63,64,65,66,67,
1,2,3,4,5,6,7,48,49,50,138,16,17,20,
101,102,103,104,105,106,146,147,148,107,108,109,110,96,
21,22,23,24,25,25,27,28,29,30,
41,42,8,9,10,46,47,
51,52,53,54,55,56,57,58,59,60,
73,74,75,71,72,18,97,98,19,129,130,
137,136,13,14,144,145,15,128,
77,78,31,32,35,76,149,150,99,100,119,
91,92,93,94,95,116,117,114,118,120,
81,82,83,84,85,122,123,
112,111,43,44,45,113,115,36,37,38,39,40,25,126,127,
131,135,61,69,70,
141,142,143,86,68,87,90,
121,88,89,124,179,80,33,34




输出文件为  output.txt

1,2,3,4,5,6,7,8,9,10,
11,12,13,14,15,16,17,18,19,20,
21,22,23,24,25,25,25,27,28,29,
30,31,32,33,34,35,36,37,38,39,
40,41,42,43,44,45,46,47,48,49,
50,51,52,53,54,55,56,57,58,59,
60,61,62,63,64,65,66,67,68,69,
70,71,72,73,74,75,76,77,78,80,
81,82,83,84,85,86,87,88,89,90,
91,92,93,94,95,96,97,98,99,100,
101,102,103,104,105,106,107,108,109,110,
111,112,113,114,115,116,117,118,119,120,
121,122,123,124,126,127,128,129,130,131,
132,133,134,135,136,137,138,139,140,141,
142,143,144,145,146,147,148,149,150,179,

实现了排序

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值