1.前言
归并排序是基于比较的排序中,最好的三个之一(其余两个为:堆排序、快速排序)
时间复杂度为 O(N*logN)
空间复杂度为 O(N)
2.内容
递归
void Partition(vector <int>& c, int L, int M, int R) //归并排序的合并过程
{
//开辟一个额外数组,存储排序后的数组
vector <int> ex(R - L + 1);
//左右指针
int l = L;
int r = M + 1;
int k = 0; //额外数组
//进行比较,并放入额外数组中
while (l <= M && r <= R) //左右指针不越界
{
ex[k++] = c[l] <= c[r] ? c[l++] : c[r++]; //先拷贝小的(若相等,先拷贝左边的)
}
//拷贝剩下的元素
while (l <= M)
{
ex[k++] = c[l++];
}
while (r <= R)
{
ex[k++] = c[r++];
}
//重新放进原数组中
int i = 0;
for (const auto& e : ex)
c[L + i++] = e;
}
void Guibingdg(vector <int>& b, int L, int R) //递归版本
{
if (L >= R)
return;
else
{
int M = L + ((R-L) >> 1); //中间位置
Guibingdg(b, L, M); //左有序
Guibingdg(b, M + 1, R); //右有序
Partition(b, L, M, R); //合并
}
}
int main()
{
srand((unsigned int)time(0));
int n;
n=rand()%10+5; //数组大小在 5~14
vector<int>a(n); //创建动态数组对象a
for (int i = 0; i < n; i++)
a[i] = rand()%10000-5000; //随机-5000~4999
for (const auto& e : a) //排序前先输出,做对比
cout << e << " ";
cout << endl;
Guibingdg(a, 0, n - 1); //递归版本的归并排序
for (const auto& e : a) //范围for语句,遍历输出
cout << e << " ";
return 0;
}
非递归(迭代版本)
void Guibingfdg(vector<int>& b,int len) //非递归版本(迭代 分而治之)
{
vector <int> c(len); //申请额外空间
for (int segment = 1; segment < len; segment *= 2) //划分部分表示每一步的步长(注意不要多加;)
{
for (int begin = 0; begin < len; begin +=segment* 2)
{
int L = begin, M = min(begin + segment, len), R = min(begin + segment * 2, len); //定义L M R,划分范围
int k = L;
int p1 = L, end1 = M;
int p2 = M, end2 = R;
while (p1 < end1 && p2 < end2) //不越界 (不加等号是因为后面的分治会考虑进去)
{ //同时符合最后一步 ==len时
c[k++] = b[p1] < b[p2] ? b[p1++] : b[p2++]; //将小的先拷贝
}
//拷贝剩余元素
while (p1 < end1)
c[k++] = b[p1++];
while (p2 < end2)
c[k++] = b[p2++];
}
//将排序好的c中元素重新拷贝回b中
for (int i = 0; i < len; i++)
b[i] = c[i];
}
}
int main()
{
srand((unsigned int)time(0));
int n;
n=rand()%10+5; //数组大小在 5~14
vector<int>a(n); //创建动态数组对象a
for (int i = 0; i < n; i++)
a[i] = rand()%10000-5000; //随机-5000~4999
for (const auto& e : a) //排序前先输出,做对比
cout << e << " ";
cout << endl;
Guibingfdg(a, n); //迭代版本的
for (const auto& e : a) //范围for语句,遍历输出
cout << e << " ";
return 0;
}
3.总结
归并排序利用了分而治之 的思想,加深理解思想
(在这里引用菜鸟教程上的图来解释)
4.更新日志
2022.5.15 整理上传
欢迎评论留言、指正~~