归并排序
介绍以下两种做法,第一种比较清晰
//将数组中l1 r1, l2 r2的数组进行排序,存放在inputList中 void mergeTwo(int* inputLlist, int left1, int right1, int left2, int right2) { int i= left1; int j = left2; int n = right1 - left1 + 1 + right2 - left2 + 1; int* tmpList = new int[n]; int k = 0; while(i <= right1 && j <= right2) { if(inputLlist[i] < inputLlist[j]) { tmpList[k++] = inputLlist[i++]; } else { tmpList[k++] = inputLlist[j++]; } } while(i <= right1) { tmpList[k++] = inputLlist[i++]; } while(j <= right2) { tmpList[k++] = inputLlist[j++]; } for(int i = 0; i < n; ++i) { inputLlist[left1 + i] = tmpList[i]; } } void mergeRecursive(int* inputList, int start, int end) { if(start < end) { int mid = (start + end) >> 1; mergeRecursive(inputList, start, mid); mergeRecursive(inputList, mid + 1, end); mergeTwo(inputList, start, mid, mid + 1, end); } } int main() { /* int a[] = {23, 47, 81, 95, 7, 14, 39, 55, 62, 74}; int b[10] = {0}; merge(a, b, 0, 3, 10); for(int i = 0; i < 10; ++i) { cout<<b[i] << " "; } cout << endl;*/ int m[] = {26, 5, 77, 1, 61, 11, 59, 15, 48, 19}; int n[10] = {0}; mergePass(m, n, 10, 1); for(int i = 0; i < 10; ++i) { cout<<n[i] << " "; } cout << endl; mergePass(n, m, 10, 2); for(int i = 0; i < 10; ++i) { cout<<m[i] << " "; } cout << endl; mergePass(m, n, 10, 4); for(int i = 0; i < 10; ++i) { cout<<n[i] << " "; } cout << endl; mergePass(n, m, 10, 8); for(int i = 0; i < 10; ++i) { cout<<m[i] << " "; } cout << endl; cout << "================test result is =================" << endl; int a[] = {26, 5, 77, 1, 61, 11, 59, 15, 48, 19}; mergeSort(a, 10); for(int i = 0; i < 10; ++i) { cout<<a[i] << " "; } cout << endl; int b[] = {26, 5, 77, 1, 61, 11, 59, 15, 48, 19}; mergeRecursive(b, 0, 9); cout << "================mergeRecursive result is =================" << endl; for(int i = 0; i < 10; ++i) { cout<<b[i] << " "; } cout << endl; cout<<"hello" << endl; return 0; }
第二种:
#include<iostream> #include<algorithm> using namespace std; void merge(int* oriList, int * resultList, int firstBegin, int firstEnd, int secondEnd) { int i, j, resultIndex; for(i = firstBegin, j = firstEnd + 1, resultIndex = firstBegin; i <= firstEnd && j < secondEnd; ++resultIndex) { if(oriList[i] < oriList[j]) { resultList[resultIndex] = oriList[i]; i++; } else { resultList[resultIndex] = oriList[j]; j++; } } copy(oriList + i, oriList + firstEnd + 1, resultList + resultIndex); copy(oriList + j, oriList + secondEnd, resultList + resultIndex); } void mergePass(int* oriList, int* resultList, const int len, int step) { int i; for(i = 0; i < len - 2*step; i = i + 2*step) { merge(oriList, resultList, i, i + step - 1, i + 2*step); } //落单的在最后一次将其合并进来,最后一次的条件是没有进入上面的for循环,也就是 if(i < len - step) { merge(oriList, resultList, i, i + step - 1, len); } else { copy(oriList + i, oriList + len, resultList + i); } } void mergeSort(int* oriList, int n) { int* tmpList = new int[n]; for(int i = 1; i < n; i = 2*i)//注意这里是以1开始的,否则会进入死循环 ,利用两次调用,巧妙地将值放在了oriList中 { mergePass(oriList, tmpList, n, i); i = 2*i; mergePass(tmpList, oriList, n, i); } delete []tmpList; }