算法学习之路(1)——二路归并排序
算法学习之路(1)——二路归并排序
基本思想是:
(1)初始时,将有n个元素的序列看成是n个长度为1的有序子序列,
(2)然后两两合并子序列,得到n/2个长度为2或1的有序子序列;再两两合并,…,直到得到一个长度为n的有序序列时结束。
算法实现例子:
(1)首先定义一个用来合并两个子序列的merge函数
方法声明:
void merge(int* source,int* temp,int leftStart,int rightStart,int rightEnd);
@param source 待排序的初始数组
@param temp 排序过程中临时存放元素的数组
@param leftStart 当前一轮比较,左边元素的下标
@param rightStart 当前一轮比较,右边元素的下标
@param rightEnd 当前一轮比较,右边子序列末端元素下标
方法实现:
void merge(int* source,int* temp,int leftStart,int rightStart,int rightEnd){ int leftEnd = rightStart - 1; int tempPos = leftStart; int numElements = rightEnd - leftStart +1; //合并两个子序列 while(leftStart <= leftEnd && rightStart <= rightEnd){ if(a[leftStart] <= a[rightStart]){ temp[tempPos++] = a[leftStart++]; }else{ temp[tempPos++] = a[rightStart++]; } } //若左边子序列长度大于右边子序列,则将左边剩余的元素复制到temp中去 while(leftStart <= leftEnd){ temp[tempPos++] = a[leftStart++]; } //若右边子序列长度大于左边子序列,则将右边剩余的元素复制到temp中去 while(rightStart <= rightEnd){ temp[tempPos++] = a[rightStart++]; } for(int i = 0;i<numElements;i++,rightEnd--){ a[rightEnd] = temp[rightEnd]; } }
(2)定义排序函数mergeSort,递归调用merge函数
函数声明:
void mergeSort(int* source,int* temp,int leftStart,int rightEnd);
@param source 源数组
@param temp 排序临时存放元素的临时数组
@param leftStart 序列的起始位置
@param rightEnd 序列的结束位置
函数实现:
void mergeSort(int* source,int* temp,int leftStart,int rightEnd){ if(leftStart<rightEnd){ int center = (leftStart+rightEnd)/2; mergeSort(source,temp,leftStart,center); mergeSort(source,temp,center+1,rightEnd); merge(source,temp,leftStart,center+1,rightEnd); } }
(3)调用该mergeSort函数对数组进行排序
函数声明:
void mergeSort(int* source,int length);
@param source 源数组
@param length 数组长度
函数实现:
void mergeSort(int* source,int length){ int* temp = new int[length]; mergeSort(source,temp,0,length-1); }
实验代码:
int main(){ int* a = new int[20]{ 1, 5, 2, 3, 6, 43, 7, 2, 7, 5, 87, 65, 32, 45, 12, 64, 31, 33, 22, 6 }; mergeSort(a,20); for (int i = 0; i < 20; i++){ cout << a[i] << " "; }
delete [] a; }
输出结果: