由于快速排序不稳定,所以大佬们引入归并。
步骤大概如下:
I、先看一组无序数组: 19 ,97 ,09, 17, 01,08
II、然后分组,先将数组序列每一个成员分成一组(如下图):
**
III、将两组按指定顺序合并到一组,我们此处由小到大,如果是自定义类记得重载比较运算符。**
IV、重复步骤III。
V、直到只有唯一一组时,排序完成,结果即为当前数组。
(理解起来是不是很简洁,时间复杂度:O(n log n))*
**
好了我们要开始敲程序了:(注意看注释)**
#include <iostream>
using namespace std;
static int number1 = 0; //debug时加上
//1、分组
template<typename T> //泛型编程是一个很好的习惯,让程序复用性更强
void devide_group(T *array, int left, int middle, int right,int *temp)
{
int k1 = right - left + 1;
temp = (T *)malloc(sizeof(T)*k1);//重新开辟临时数组空间
int i = left, j = middle + 1, num = 0;
//有一个比较到指定位置则结束循环,比如左侧数组边只比较了前两个位置,但是右侧已经遍历完
//则此时的意思是左侧剩余的元素大于右侧所有的元素,再将剩余的元素接在临时数组当前第一个空缺位置处即可
while (i <= middle && j <= right)
{
if (array[i] <= array[j]) //左边数组从左到右跟右边组比较大小
{
temp[num++] = array[i++]; //左边大则将 i 位置元素放置在临时数组第一个空位置
}
else if (array[i] > array[j])左边小则将右侧 j 元素放置在临时数组第一个空缺位置
{
temp[num++] = array[j++];
}
}
if (i <= middle) //判断前一组是否比较完毕,后一组不需要,
// 因为相对于原数组来说,后一组剩下元素肯定是大于前面所有元素的,位置不会发生改变。
{
temp[num++] = array[i++];
};
//if (j <= right) //判断前一组是否比较完毕,后一组不需要,因为相对于原数组来说,后一组剩下元素肯定是大于前面所有元素的,位置不会发生改变。
//{
// temp[num++] = array[j++];
//};
cout << "当前排序:" << "left:" << left << " ~ " << right << " value: ";
for (int k = 0; k < j-left; k++)
{
array[left++] = temp[k];
cout << array[left - 1] << " ";
}
cout << endl;
free(temp); //分配的空间记得释放哟
temp = NULL;
}
template<typename T>
void merge_soft(T*array, int left, int right,int *temp) //最末和最开始
{
if (left >= right)
{
return;
}
int middle = (right + left) / 2;
merge_soft(array, left, middle,temp); //迭代使左侧分组每一组到只剩一个元素,然后调回上一层迭代跟另一组比较。
merge_soft(array, middle + 1, right,temp);
devide_group<T>(array, left, middle, right,temp); //将排序好的两组再进行排序
cout << "此时";
while (left <= right)
{
cout << array[left++];
}
cout << "序号 " << number1++ << endl;
}
int main()
{
int array[7] = { 1,2,5,6,3,4,5 };
int *temp = NULL;
merge_soft<int>(array, 0, 6,temp);
cout << array[4] << " ";
//devide_group<int>(array, 4,5, 6);
cout << "排序后:";
for (int i = 0; i < 7; i++)
{
cout << array[i];
}
cout << endl;
}
复习代码:
void fun(int *a, int low,int low_h,int high_l,int high)
{
int size = high - low + 1;
int *temp = new int[size];
int i = low, j = high_l;
int num = 0;
while (i <= low_h && j <= high)
{
if (a[i] < a[j])
{
temp[num++] = a[i];
i++;
}
if (a[i] >= a[j])
{
temp[num++] = a[j];
j++;
}
}
if (i != low_h)
{
for (int k = i; i <= low_h; i++)
{
temp[num++] = a[i];
}
}
for (int q1 = low; q1 <j; ++q1)
{
cout << "此时temp[ ] " << temp[q1 - low] << " 此时a " << a[q1] << endl;
a[q1] = temp[q1 - low];
}
delete [] temp;
temp = nullptr;
}
void merger(int *a, int low, int high)
{
if (low == high)
{
return ;
}
int middle = (low + high) / 2;
merger(a,low, middle);
merger(a,middle+1, high);
fun(a, low, middle, middle + 1, high);
return ;
}
图片来源:https://www.bilibili.com/video/BV1et411N7Ac?from=search&seid=4632645683604929268