经典的归并算法是每次n/2分,然后再合并排序。而本算法是将n维数组每次分为根号n后递归后归并排序,思想和二路归并类似,但稍有不同
#include #include using namespace std; template class SortableList { public: SortableList(int m) { n = m; } void MergeSort(); void Merge(int left, int mid, int right); void Input(); void Init(); void Output(); private: void MergeSort(int left, int right); T l[1000];//输入的数组值 T a[1000];//实际排序对象 int n; }; template void SortableList::Input() { for(int i = 0; i < n; i++) cin >> l[i]; } template void SortableList::Init() { for(int i =0; i < n; i++) a[i] = l[i]; } template void SortableList::Output() { for(int i = 0; i < n; i++) cout << a[i] << " "; cout << endl << endl; } template void SortableList::MergeSort() { MergeSort(0, n - 1); } template void SortableList::MergeSort(int left, int right) { if(left < right) //控制 当调用至序列只剩一个元素结束函数向上层递归执行 { int sq = (int) sqrt((double) (right - left + 1)); for(int i = 0; i < sq; i++) { MergeSort(left + i * sq, left + (i + 1) * sq - 1); } if(left + sq * sq <= right) MergeSort(left + sq * sq, right); for(int j = 1; j < sq; j++) { Merge(left, left + sq * j - 1,left + sq * (j+1) - 1); } if(left + sq * sq <= right) Merge(left, left + sq * sq - 1, right); //排序 } } template void SortableList::Merge(int left, int mid, int right) { //a数组为待排序的数组 T* temp =new T[right - left + 1]; //temp数组用来暂时保存排序好的数组 int i = left, j = mid + 1, k = 0; //left 至mid为左半数组 ,mid+1至right为右半数组 while((i <= mid)&&(j <= right)) //对应第一步 当左半数组和右半数组都不为空时 if(a[i] <= a[j]) //输出两个数组中的较小者 temp[k ++] = a[i ++]; else temp[k ++] = a[j ++]; while(i <= mid) //当一数组为空时,输出另一数组的剩余元素 temp[k ++] = a[i ++]; while(j <= right) //当一数组为空时,输出另一数组的剩余元素 temp[k ++] = a[j ++]; for(i = 0, k = left; k <= right;) //将temp数组赋值给原数组 a[k ++] = temp[i ++]; } int main() { int m; cout << "数组长度n: "; cin >> m; SortableList List(m); cout << "输入" << m << "个数字:" << endl; List.Input(); List.Init();//得到初始状态 List.MergeSort(); cout << "合并排序后:" << endl; List.Output(); return 0; }