1.13 归并排序
1.13.1 介绍
**归并排序(Merging Sort)**是利用归并的思想实现的排序算法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分成一些小的问题然后递归求解,而治的阶段则将分的阶段得到的各答案“修补”在一起,即分而治之)。
1.1.3.2 原理
归并排序思想示意图1——基本思想:
归并排序思想示意图2——合并相邻有序子序列::
1.13.3 归并排序实现
注:sort.h 在c语言排序总结—前序准备中
归并排序代码实现:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include "sort.h"
int main() {
//生成LENGTH长度的随机数组,并展示出来
int arr[LENGTH];
createRandomArray(arr);
int count = 0;
for (int i = 0; i < LENGTH; i++) {
printf("%-10d", arr[i]);
count++;
if (count % 10 == 0) {
printf("\n");
}
}
printf("\n");
//统计排序的时间
int begin, end;
begin = clock();
//调用排序
mergingSort(arr);
end = clock();
//输出排序结果
for (int i = 0; i < LENGTH; i++) {
printf("%-10d", arr[i]);
count++;
if (count % 10 == 0) {
printf("\n");
}
}
//输出排序时间
printf("排序时间为time=%d\n", end - begin);
system("pause");
}
void mergingSort(int arr[]) {
int temp[LENGTH];
mSort(arr, temp, 0, LENGTH-1);
}
void mSort(int arr[], int temp[], int left, int right) {
if (left < right){
//中间索引
int mid = (left + right) / 2;
//向左递归进行分解
mSort(arr, temp, left, mid);
//向右递归进行分解
mSort(arr, temp, mid + 1, right);
//合并
merge(arr, temp, left, mid, right);
}
}
void merge(int arr[], int temp[], int left, int mid, int right) {
int i = left;//初始化i,左边有序序列的初始索引
int j = mid + 1;//初始化j,右边有序序列的初始索引
int t = 0;//指向temp数组的当前索引
//(1)
//先把左右两边(有序)的数据按照规则填充到temp
//直到左右两边的有序序列,有一边处理完为止
while (i <= mid && j <= right) { // 继续
//如果左边的有序序列的当前元素,小于等于右边有序序列的当前元素
//即将左边的当前元素填充到temp数组
//然后t++,i++
if (arr[i] <= arr[j]) {
temp[t] = arr[i];
t++;
i++;
}
else {//反之将右边有序序列的当前元素,填充到temp数组
temp[t] = arr[j];
t++;
j++;
}
}
//(二)
//把有剩余数据的一遍的数据依次全部填充到temp
while (i <= mid) {//左边的有序序列还有剩余的元素,就全部填充到temp
temp[t] = arr[i];
t += 1;
i += 1;
}
while (j <= right) {//右边边的有序序列还有剩余的元素,就全部填充到temp
temp[t] = arr[j];
t += 1;
j += 1;
}
//(三)
//将temp数组的元素拷贝到arr
//注意并不是每次都拷贝所有
t = 0;
int tempLeft = left;
while (tempLeft <= right) {
arr[tempLeft] = temp[t];
t += 1;
tempLeft += 1;
}
}
归并排序在10000数据量下的耗时结果为1毫秒:
归并排序在10万数据量下的耗时结果为18毫秒: