目录
概念
并归是一种排序的基本算法。
当我们拿到一个乱序的数组的时候,我们可以用并归进行排序。
并归的大致组成
并归分为两部分,第一部分是拆,第二是并。
拆
拆是把乱序的数组对半拆成一个一个数组,直到左端等于右端的下标。
即将序列两两分组,将序列归并为n/2^m,n是数组元素个数,m是第几次拆分,再组内单独排序。
并
并是把拆完的数组再一个一个合并回一个较大的数组,中间要用到递归的思想。
递归又分为两部分,递推和回归
递推
先传入一个数组,不断对半拆
if (left < right)
{
int mid = (left + right) / 2;
merg_sort(arr, left, mid);
merg_sort(arr, mid + 1, right);
rank(arr, left, mid, mid + 1, right);
}
回归
回归是先回小的部分,再回大的部分
例子:
代码实现
#include<stdio.h>
#define max 100
//排序合并函数
void rank(int arr[], int l1, int r1, int l2, int r2)
{
int temp[max];//临时数组
int index = 0;
int i = l1;//i是前半部分的开头
int j = l2;//j是后半部分的开头
while (i <= r1 && j <= r2)
{
//先对比两部分元素的大小
if (arr[i] < arr[j])
{
temp[index] = arr[i];
index++;
i++;
}
if (arr[i] > arr[j])
{
temp[index] = arr[j];
index++;
j++;
}
if (arr[i] == arr[j])
{
temp[index] = arr[i];
index++;
i++;
j++;
}
//这样一比完,一定前半部分或者后半部分的先左右端相等
}
//继续存储还没有比完的元素
while (i <= r1)
{
temp[index] = arr[i];
i++;
index++;
}
while (j <= r2)
{
temp[index] = arr[j];
j++;
index++;
}
//返回临时变量里已经比完的元素给arr
for (int i = 0; i < index; i++)
{
arr[l1+i] = temp[i];
//因为是不断对半分后传过来的数组,所以前半部分的0下标才是排序的开始,
//即是从arr[l1]开始排序,不是从arr[0]开始排序
}
}
void merg_sort(int arr[], int left, int right)
{
if (left < right)
{
int mid = (left + right) / 2;//对半分
//递归
merg_sort(arr, left, mid);//前半部分
merg_sort(arr, mid + 1, right);//后半部分
//合并排序
rank(arr, left, mid, mid + 1, right);//合并前后半部分
}
}
int main()
{
int arr[] = { 1,22,3,4,5,44,6,66,7 };
merg_sort(arr, 0, 9 - 1);
for (int i = 0; i < 9; i++)
{
printf("%d ", arr[i]);
}
return 0;
}