| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 438 人关注过本帖
标题:直接归并排序
只看楼主 加入收藏
asdgzw1
Rank: 1
等 级:新手上路
帖 子:9
专家分:0
注 册:2013-6-20
结帖率:100%
收藏
 问题点数:0 回复次数:1 
直接归并排序
  如:FC文件(20个元素): 5 15 35 30 20 45 35 5 65 75 40 50 60 70 30 40 25 10 45 55

  步骤1:FC文件分割为各含10个单元素的两个临时文件FA,FB中。

  FA: {5 35},{20 35}, {65 40 },{60 30 }, {25 45}

  FB: {15 30} , {45 5} , {75 50} , {70 40}, {10 55}

  步骤2:FA与FB归并排序成2元素的有序子表

  FC: {5 15} {30 35},{20 45} {5 35},{65 75} {40 50},{60 70} {30 40},{10 25} {45 55}

  步骤3: 继续将FC拆分为FA,FB,再次归并为FC中的4元素子表

  FA: {5 15},{20 45},{65 75},{60 70},{10 25}

  FB: {30 35},{5 35},{40 50},{30 40},{45 55}

  FC: {5 15 30 35},{5 20 35 45},{40 50 65 67},{30 40 60 70},{10 25 45 55}

  ...继续归并(8元素->16元素->20元素)...

  步骤6: 归并为FC中20个元素即得到完整的有序文件。

  



  修改直接归并排序,从较长子表开始,更高效的完成排序。算法根据文件FC和一个内存缓冲区建立有序子表。我们将原始文件中的数据以块形式读入到缓冲区中,然后用一种快速内部排序法(QuickSort)将块排好序。这些块被交替复制到文件fA和fB中。归并从具有较大初始长度的子表开始。

  template

  void MergeSort(BinFile& fc,int blockSize)

  { BinFile fA("fileA",INOUT);

  BinFile fB("fileB",INOUT);

  int size= int(fC.Size()),n=blockSize; //文件大小及块大小

  int k=1,useA=1,readCount;

  T * A;

  fC.Reset(); //重置fc指针指向文件头

  if(size <= blockSize) //对于fc小文件,从fc读入数据,排序后写回fc中

  { A=new T[size]; //申请存放数据的缓冲区并读入一块数据

  if(A==NULL) //内存分配出错

  { cerr<<"MergeSort:memory allocation failure."<

  exit(1);

  }

  fC.Read(A,size); //将fC的数据读入A中

  QuickSort(A,0,(int)size-1); //对A进行快速排序

  fC.Clear(); //清空文件fc并将排序后的数据写回文件fc中

  fC.Write(A,size);

  delete [] A; //释放缓冲区并返回

  return;

  }

  else //如果文件大小超过了块大小

  { A = new T[blockSize];

  if(A==NULL) //内存分配出错

  { cerr<<"MergeSort:memory allocation failure."<

  exit(1);

  }

  while(!fC.EndFile())

  { readCount=fC.Read(A,blockSize); //读取blockSize大小的数据块文件

  if(readCount==0) //如果没有读到数据返回

  break;

  //对数据块排序并交替写入到文件文件fA和fB中

  QuickSort(A,0,readCount-1);

  if(useA) //如果用到FA

  { fA.Write(A,readCount);

  }else

  { fB.Write(A,readCount);

  }

  useA = !useA;

  }

  delete [] A; //数据写完释放A内存空间

  }

  Merge(fA,fB,fC,blockSize);// 将两个文件fA和fB中块大小为blockSize的归并段写回到fC中

  k*=2; //将当前归并段大小加倍

  n=k*blockSize;

  while(n>文件大小时,fC仅剩下一个已排好序的归并段

  { Split(fA,fB,fC,k,blockSize); //循环分离归并段

  Merge(fA,fB,fC,n);//排序后再重新写回fc

  k*=2; //归并段循环加倍

  n=k*blockSize; //加倍后的块大小

  }

  //删除临时文件

  fA.Delete();

  fB.Delete();

  }
编辑tt娱乐城:http://www.
搜索更多相关主题的帖子: 元素 
2013-06-22 14:16
蚕头燕尾
Rank: 10Rank: 10Rank: 10
来 自:Gryffindo
等 级:贵宾
威 望:12
帖 子:734
专家分:1546
注 册:2013-3-24
收藏
得分:0 
话说楼主的问题是什么



学习编程,为的是表达自己的思想,而不是被别人的思想所禁锢。要先明白自己想干嘛,而不要先问别人让你干嘛。               

                                                                                                                    Black Cat      Hello Tomorrow~
2013-06-22 20:06
快速回复:直接归并排序
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.011923 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved