归并排序
1.思想
将一个需要排序的数组分为(递归的)两半分别排序,然后将结果归并起来
2.实现过程
归并排序的过程是一个分治递归的过程
写递归一个步骤
1.写出递推表达式和终止条件
2.实现递推代码
os:是不是很简单,才怪!!!
归并排序的递推式
递推公式:
merge_sort(lo…hi) = merge(merge_sort(lo…mid), merge_sort(mid+1…hi))
终止条件:
lo >= hi不用再继续分解
merge函数的作用是归并两个数组
当lo < hi时持续递归
代码实现
排序过程
第一个mereSort过程一次性分配空间,为并归过程提供辅助数组,并调用mereSort重载方法,这么做的为了递归的方便,不用在递归过程中分配空间,创建数组。
void mereSort(vector<int>& data)
{
int n = data.size();
aux = new int[n];//一次性分配空间
mereSort(data,0,n-1);
}
void mereSort(vector<int>& data , int lo , int hi)
{
if (lo >= hi) return;
int mid = lo + (hi - lo) / 2;
mereSort(data, lo, mid);
mereSort(data, mid + 1, hi);
merge(data, lo,mid,hi);
}
归并过程
并归过程可以有多种实现,只要能合并两个有序数组就行
归并实现1
void merge(vector<int>& data , int lo , int mid , int hi)
{
int i = lo, j = mid + 1;
for (int k = lo; k <= hi; k++)
aux[k] = data[k]; //将数组元素拷贝到辅助数组
for (int k = lo; k <= hi; k++)
{
if (i > mid) data[k] = aux[j++];
else if (j > hi) data[k] = aux[i++];
else if (aux[i] < aux[j]) data[k] = aux[i++];
else data[k] = aux[j++];
}
}
归并实现2
void merge2(vector<int>& data, int lo, int mid, int hi)
{
int i = lo, j = mid + 1;
int k = 0;
//分别从lo-mid、mid+1-hi之间选取元素,拷贝到辅助数组
while (i <= mid&& j <= hi)
{
if (data[i] < data[j])
{
aux[k++] = data[i++];
}
else
{
aux[k++] = data[j++];
}
}
//判断子数组是否拷贝完,若没有拷贝完,继续拷贝
while(i<=mid)
aux[k++] = data[i++];
while (j <= hi)
aux[k++] = data[j++];
//把合并好的辅助数组中的元素复制回原数组
int t = 0;
for (int k = lo; k <=hi; k++)
{
data[k] = aux[t++];
}
}
并归排序的时间复杂度O(nlogn)、空间复杂度O(n)