一. 归并排序
今天讲解的是归并排序,归并排序就是我觉得可以将其称为区间排序,它的整个过程就是将一个数组不断地对半拆分,最后拆成两对两对,在进行排序,如何再将相邻地两队分别合并排序,直至最后将mid左右两边的区间进行合并排序。
动态如图:
代码如下:
#include <stdio.h>
#include <stdlib.h>
void MergeSort(int *nums, int l, int r){
if(l >= r)return ;
//tmp用来进行中间存储
int* tmp = (int *) malloc(sizeof(int) * (r - l + 1));
int mid = (l + r) / 2;
MergeSort(nums, l, mid);//向左拆分
MergeSort(nums, mid + 1, r);//右拆分
int p = 0;
int lp = l, rp = mid + 1;
while(lp <= mid || rp <= r){
if(lp > mid){
//如果lp > mid 说明左边以及排好了,直接排右边
tmp[p++] = nums[rp++];
}
else if(rp > r){
//如果rp > r说明右边以及排好了
tmp[p++] = nums[lp++];
}
else{
if(nums[lp] < nums[rp]){
tmp[p++] = nums[lp++];
}
else{
tmp[p++] = nums[rp++];
}
}
}
//将tmp复制到nums上
for(int i = 0; i < r - l + 1; i++){
nums[l + i] = tmp[i];
}
free(tmp);
}
int main(){
int arr[] = {
8, 5, 6, 4, 3, 7, 10, 2};
int r = sizeof(arr) / sizeof(arr[0]);
MergeSort(arr, 0, r - 1);
for(int i= 0; i < r; i++){
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
二. 相关练习
题目链接:
164. 最大间距
这道题我们直接用归并排序即可
代码如下:
void MergeSort(int *nums, int l, int r){
if(l >= r)return ;
int* tmp = (int*) malloc (sizeof(int) * (r - l + 1));
int mid = (l + r) / 2;
MergeSort(nums, l, mid);
MergeSort(nums, mid + 1, r);
int p = 0;
int lp = l, rp = mid + 1;
while(lp <= mid || rp <= r){
if(lp > mid){
tmp[p++] = nums[rp++];
}
else if(rp > r){
tmp[p++] = nums[lp++];
}
else{
if(nums[lp] < nums[rp]){
tmp[p++] = nums[lp++];
}
else{
tmp[p++] = nums[rp++];
}
}
}
for(int i = 0; i < r - l + 1; i++){
nums[l + i] = tmp[i];
}
free(tmp);
}
int maximumGap(int* nums, int numsSize){
if(numsSize < 2){
return 0;
}
MergeSort(nums, 0, numsSize - 1);
int maxGap = 0;
for(int i = 0; i < numsSize - 1; i++){
int k = abs(nums[i] - nums[i + 1]);
if(k > maxGap){
maxGap = k;
}
}
return maxGap;
}