/**
归并操作:
归并操作(merge),也叫归并算法,指的是将两个已经排序的序列合并成一个序列的操作。归并排序算法依赖归并操作。
算法描述:
归并操作的过程如下:
1.申请空间 ,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
2.设定两个指针,最初位置分别为两个已经排序序列的起始位置
3.比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
4.重复步骤3直到某一指针达到序列尾
5.将另一序列剩下的所有元素直接复制到合并序列尾
即:
归并排序具体工作原理如下(假设序列共有n个元素):
将序列每相邻两个数字进行归并操作(merge),形成floor(n/2)个序列,排序后每个序列包含两个元素
将上述序列再次归并,形成floor(n/4)个序列,每个序列包含四个元素
重复步骤2,直到所有元素排序完毕
示例代码:
以下示例代码实现了归并操作。array[]是元素序列,其中从索引p开始到q位置,按照升序排列,同时,从(q+1)到r也已经按照升序排列,
merge()函数将把这两个已经排序好的子序列合并成一个排序序列。结果放到array中。
*/
#include <IOSTREAM.H>
//using namespace std;//#include <IOSTREAM>时加上该语句
//#只完成两段之间归并的功能#%
void Merge(int a[], int b[], int low, int mid, int high)
{
int k = low;
int begin1 = low;
int end1 = mid;
int begin2 = mid + 1;
int end2 = high;
//两段的开始位置小于结尾标志时
while(begin1 <= end1 && begin2 <= end2)
{
if(a[begin1] <= a[begin2])
{
b[k++] = a[begin1++];
}
else
{
b[k++] = a[begin2++];
}
}
//
if(begin1 <= end1)
{
for(int q = begin1; q <= end1; q++)
{
b[k++] = a[q];
}
}
else
{
for(int q = begin2; q <= end2; q++)
{
b[k++] = a[q];
}
}
}
void MergePass(int a[], int b[], int seg, int size)
{
int seg_start_ind = 0;
while(seg_start_ind <= size - 2 * seg) //#size - 2 * seg的意思是滿足可兩兩歸併的最低臨界值#%
{
Merge(a, b, seg_start_ind, seg_start_ind + seg - 1, seg_start_ind + seg * 2 - 1);
seg_start_ind += 2 * seg;
}
//#如果一段是正好可歸併的數量而另一段則少於正好可歸併的數量#%
if(seg_start_ind + seg < size)
Merge(a, b, seg_start_ind, seg_start_ind + seg - 1, size - 1);
else
for(int j = seg_start_ind; j < size; j++) //#如果只剩下一段或者更少的數量#%
b[j] = a[j];
}
void MergeSort(int a[], int size)
{
int* temp = new int[size];
int seg = 1;
while(seg < size)
{
MergePass(a, temp, seg, size);
seg += seg;
MergePass(temp, a, seg, size);
seg += seg;
}
}
int main()
{
int a[] = {3, 5, 3, 6, 4, 7, 5, 7, 4}; //#QQ#%
MergeSort(a, sizeof(a) / sizeof(*a));
//#輸出#%
for(int i = 0; i < sizeof(a) / sizeof(*a); i++)
cout << a[i] << ' ';
cout << endl;
return 0;
}