/***********************************************************************************************
1.設定兩個指針,最初位置分別為兩個已經排序序列的起始位置
2.比較兩個指針所指向的元素,選擇相對小的元素放入到合並空間,並移動指針到下一位置
3.重復步驟3直到某一指針達到序列尾
4.將另一序列剩下的所有元素直接復制到合並序列尾
歸並排序:
歸並排序具體工作原理如下(假設序列共有n個元素):
1.將序列每相鄰兩個數字進行歸並操作,形成floor(n / 2)個序列,排序后每個序列包含兩個元素
2.將上述序列再次歸並,形成floor(n / 4)個序列,每個序列包含四個元素
3.重復步驟2,直到所有元素排序完畢
歸並排序是穩定的,它的最差,平均,最好時間都是O(nlogn)。但是它需要額外的存儲空間.
何問起 hovertree.com
歸並排序法(Merge Sort,以下簡稱MS)是分治法思想運用的一個典范。
其主要算法操作可以分為以下步驟:
Step 1:將n個元素分成兩個含n/2元素的子序列
Step 2:用MS將兩個子序列遞歸排序(最后可以將整個原序列分解成n個子序列)
Step 3:合並兩個已排序好的序列
************************************************************************************************/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<climits>
#include<cstdlib>
#include<time.h>
#include<cstdlib>
#include<cstdio>
using namespace std;
void Random(int a[],int n)
{
int i=0;
srand( (unsigned)time( NULL ) );
while(i<n)
{
a[i++]=rand();
}
}
void merge(int *a, int low, int mid, int high) //歸並操作
{
int k, begin1, begin2, end1, end2;
begin1 = low;
end1 = mid;
begin2 = mid + 1;
end2 = high;
int *temp = (int *) malloc((high - low + 1) * sizeof(int));
for(k = 0; begin1 <= end1 && begin2 <= end2; k++) //自小到大排序
{
if(a[begin1] <= a[begin2])
temp[k] = a[begin1++];
else
temp[k] = a[begin2++];
}
if(begin1 <= end1) //左剩
memcpy(temp + k, a + begin1, (end1 - begin1 + 1) * sizeof(int));
else //右剩
memcpy(temp + k, a + begin2, (end2 - begin2 + 1) * sizeof(int));
memcpy(a + low, temp, (high - low + 1) * sizeof(int)); //排序后復制到原數組
free(temp); //釋放空間
}
void merge_sort(int *a, unsigned int begin, unsigned int end)
{
int mid;
if(begin < end)
{
mid=begin+(end-begin)>>1;
//mid = (end + begin) / 2; 防止數據加法溢出
merge_sort(a, begin, mid); //分治
merge_sort(a, mid + 1, end); //分治
merge(a, begin, mid, end); //合並兩個已排序的數列
}
}
int main()
{
int a[20];
Random(a,20);
for(int i=0;i<20;i++)
{
cout<<" "<<a[i]<<" ";
}
merge_sort(a, 0, 20-1);
for(int i=0;i<20;i++)
{
cout<<" "<<a[i]<<endl;
}
return 0;
}
推薦:http://www.cnblogs.com/roucheng/p/cppjy.html