演算法描述
歸併操作的過程如下:
- 申請空間,使其大小為兩個已經排序序列之和,該空間用來存放合并後的序列
- 設定兩個指標,最初位置分別為兩個已經排序序列的起始位置
- 比較兩個指標所指向的元素,選擇相對小的元素放入到合并空間,並移動指標到下一位置
- 重複步驟3直到某一指標達到序列尾
- 將另一序列剩下的所有元素直接複製到定序序列尾
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
//歸併排序,升序。
void Merge(int a[],int b[],int left,int mid,int right)
{
int k = left;
int i;
int begin1 = left;
int end1 = mid;
int begin2 = mid+1;
int end2 = right;
while(begin1<=end1&&begin2<=end2)
{
if(a[begin1]<=a[begin2])
{
b[k++] = a[begin1];
begin1++;
}
else
{
b[k++] = a[begin2];
begin2++;
}
}
//第一段沒有比較完的情況
if(begin1<=end1)
{
for(i = begin1;i<=end1;i++)
b[k++] = a[i];
}
//第二段還沒有比較完的情況
else
{
for(i = begin2;i<=end2;i++)
b[k++] = a[i];
}
}
void MergePass(int a[],int b[],int seg,int size)
{
int seg_start_index = 0;
int i;
while(seg_start_index<=size-2*seg)//可滿足兩兩合并的最低界限值
{
Merge(a,b,seg_start_index,seg_start_index+seg-1,seg_start_index+2*seg-1);
seg_start_index += 2*seg;
}
//如果一段剛好是可以合并的長度,另一段則少於正好可和並的長度
if(seg_start_index+seg<size)
{
Merge(a,b,seg_start_index,seg_start_index+seg-1,size-1);
}
//如果正好只剩一段或者少於一段的長度
else
{
for(i = seg_start_index;i<size;i++)
b[i] = a[i];
}
}
void Merge_Sort(int a[],int size)
{
int seg;//需要排序合并的段的大小
int *tmp = new int[size];
seg = 1;
while(seg<size)
{
MergePass(a,tmp,seg,size);
seg +=seg;
MergePass(tmp,a,seg,size);
seg += seg;
}
}
int main()
{
int num[] = {1,4,6,2,8,7,3,5,9,0};
int i;
Merge_Sort(num,sizeof(num)/sizeof(num[0]));
for(i = 0;i<sizeof(num)/sizeof(num[0]);i++)
{
cout<<num[i]<<" ";
}
cout<<endl;
return 0;
}