一、非递归
基本思想:
归并排序( MERGE-SORT )是建立在归并操作上的一种有效的排序算法 , 该算法是采用分治法( Divide andConquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。 归并排序核心步骤:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
void _MergeSort(int* a, int begin, int end, int* temp)
{if (begin>=end)return;int mid = (begin + end) / 2;//[begin,mid] [mid+1,end]如果这两个区间有序,那么可以归并了_MergeSort(a, begin, mid, temp);_MergeSort(a, mid+1, end, temp);//[begin, mid] [mid + 1, end]归并int begin1 = begin, end1 = mid;int begin2 = mid+1, end2 = end;int i = begin;while (begin1 <= end1 && begin2 <= end2){if (a[begin1] < a[begin2]){temp[i] = a[begin1];i++;begin1++;}else{temp[i] = a[begin2];i++;begin2++;}}//谁没结束谁++来拷贝,由于不知道是哪个区间没有结束,所有都写一遍while (begin1 <= end1){temp[i] = a[begin1];i++;begin1++;}while (begin2 <= end2){temp[i] = a[begin2];i++;begin2++;}//等把所有数都放到temp数组上时,再拷贝回去memcpy(a+begin, temp+begin,sizeof(int)*(end-begin+1));
}
void MergeSort(int* a, int n)
{int* temp = (int*)malloc(sizeof(int) * n);if (temp == NULL){perror("malloc fail\n");return;}_MergeSort(a, 0, n - 1, temp);free(temp);
}
int main()
{int a[] = {10,6,7,1,3,9,4,2 };MergeSort(a,8);for (int i = 0; i < 8; i++){printf("%d ", a[i]);}return 0;
}
注:以下图片看不清楚可以点进去放大看
二、递归
不能用栈,栈是前序,而归并是后序
方法:
能不能依次依次往后算?算完第一个和第二个后算第三个和第四个,再算第五个和第六个.......
第一次归完后再拷贝回去后四个四个一归.....

必须得注意细节:如果是奇数个数那么得注意边界
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
void Swap(int* a, int* b)
{int temp = *a;*a = *b;*b = temp;
}
void _MergeSort(int* a, int begin, int end, int* temp)
{if (begin >= end)return;int mid = (begin + end) / 2;//[begin,mid] [mid+1,end]如果这两个区间有序,那么可以归并了_MergeSort(a, begin, mid, temp);_MergeSort(a, mid + 1, end, temp);//[begin, mid] [mid + 1, end]归并int begin1 = begin, end1 = mid;int begin2 = mid + 1, end2 = end;int i = begin;while (begin1 <= end1 && begin2 <= end2){if (a[begin1] < a[begin2]){temp[i] = a[begin1];i++;begin1++;}else{temp[i] = a[begin2];i++;begin2++;}}//谁没结束谁++来拷贝,由于不知道是哪个区间没有结束,所有都写一遍while (begin1 <= end1){temp[i] = a[begin1];i++;begin1++;}while (begin2 <= end2){temp[i] = a[begin2];i++;begin2++;}//等把所有数都放到temp数组上时,再拷贝回去memcpy(a + begin, temp + begin, sizeof(int) * (end - begin + 1));
}
void MergeSort(int* a, int n)
{int* temp = (int*)malloc(sizeof(int) * n);if (temp == NULL){perror("malloc fail\n");return;}int gap = 1;while (gap < n){for (int i = 0; i < n; i += 2 * gap){int begin1 = i, end1 = i + gap - 1;int begin2 = i + gap, end2 = i + 2 * gap - 1;int j = i;while (begin1 <= end1 && begin2 <= end2){if (a[begin1] < a[begin2]){temp[j] = a[begin1];j++;begin1++;}else{temp[j] = a[begin2];j++;begin2++;}}//谁没结束谁++来拷贝,由于不知道是哪个区间没有结束,所有都写一遍while (begin1 <= end1){temp[j] = a[begin1];j++;begin1++;}while (begin2 <= end2){temp[j] = a[begin2];j++;begin2++;}//等把所有数都放到temp数组上时,再拷贝回去memcpy(a + begin, temp + begin, sizeof(int) * (end - begin + 1));}gap *= 2;}free(temp);
}
int main()
{int a[] = {10,6,7,1,3,9,4,2 };MergeSort(a,8);for (int i = 0; i < 8; i++){printf("%d ", a[i]);}return 0;
}