写给自己的,避免忘记!!
合并排序算法采用先分治,再合并的思路。此思路根据算法导论原理,在合并算法中,是将两个已经排序好的数组进行合并。
我的算法是可以对任意可变数组进行排序,对于待合并的数组元素为n,最多比较n次,为实现高效率,避免每次检查数组,检查到最后导致溢出,在每一个数组后面加一个哨兵,哨兵一般取计算机所能达到的最大值,当其中一个数组出现哨兵时,说明该数组已经排序完成,此后另外一个数组每次比较时都是与那个哨兵比较,相当于把另外一个数组的值直接添加到待合并的数组中。其代码如下:
void Insert::Merge(vector<int>& A,vector<int>& sub1,vector<int>& sub2)//sub1,sub2为已排好的数组
{
sub1.push_back(65535);//哨兵
sub2.push_back(65535);
int number1=sub1.size();
int number2=sub2.size();
int i=0,j=0;
for(auto pos=A.begin();pos!=A.end();++pos )
{
if(sub1[i]<= sub2[j])
{
*pos=sub1[i];
++i;
}
else
{
*pos=sub2[j];
++j;
}
}
}
A为引用,其数组元素的个数为sub1和sub2的元素个数之和。sub1和sub2都要为引用,不然递归后排序会失效。合并算法代码如下:
void Insert::MergeSort(vector<int>& coll)//合并排序,先分治法,再合并
{
unsigned int number=coll.size();
if(number<=1)
return;
unsigned int mid=number/2;
vector<int> sub1;
vector<int> sub2;
for(unsigned int i=0;i<mid;++i)
{
sub1.push_back(coll[i]);
}
for(unsigned int j=0;j<number-mid;++j)
{
sub2.push_back(coll[mid+j]);
}
MergeSort(sub1);
MergeSort(sub2);
Merge(coll,sub1,sub2);
}
coll为待排序的数组,一直这样递归下去,从底向上进行合并排序,到递归到最底层时,sub1,sub2只有个1个元素,可认为已经排好序,然后通过sub1和sub2引用,向上合并都是已经排好序的,一直到最上层,coll就已经被排好序了。
要注意的是:sub2.push_back(coll[mid+j]);此处是mid+j,这是我写代码时出现的错误,给自己提醒。
主函数如下:
Insert insert;
vector<int> coll;
int value=0;
while(cin>>value)
{
coll.push_back(value);
}
insert.MergeSort(coll);//合并排序
for(auto pos=coll.begin();pos!=coll.end();++pos)
{
cout<<*pos<<' ';
}
system("pause");
时间复杂度为O(n*lgn),如有合并排序的更好算法,敬请赐教,相互交流!