数据结构 排序(归并排序)
思想: 分而治之,将数组递归二等分拆解直至每个数组只有一个元素,然后相邻两组元素有序归并。
时间复杂度: O(nlogn)
//归并排序--递归算法的运用 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<time.h> #include <math.h> //打印数组 void show(int* arr, int num) { int i = 0; for (i = 0; i < num; i++) { printf("%5d", *(arr + i)); } printf("\n"); } void merge(int* arr, size_t left, size_t right) { int * tmp; size_t mid; size_t capacity, i, j, k; capacity = right - left + 1; mid = (left + right) >> 1; i = left; j = mid + 1; k = 0; // 分配临时内存 tmp = calloc(capacity, sizeof(int)); if (NULL == tmp) { return; } while (i <= mid && j <= right) { if (arr[i] < arr[j]) { tmp[k++] = arr[i++]; } else { tmp[k++] = arr[j++]; } } while (i <= mid) { tmp[k++] = arr[i++]; } while (j <= right) { tmp[k++] = arr[j++]; } // 覆盖原先数据 for (i = left, k = 0; i <= right; i++, k++) { arr[i] = tmp[k]; } free(tmp); tmp = NULL; } void merge_sort(int* arr, size_t left, size_t right) { size_t mid; if (left >= right) { return; } // 计算中间下标 mid = (left + right) >> 1; /* 设计说明: 拆分元素的时候不用分配内存,合并元素时才需要分配内存 */ merge_sort(arr, left, mid); merge_sort(arr, mid + 1, right); merge(arr, left, right); } void test() { int i = 0; int arr[10] = { 0 }; time_t ts; //生成随机数种子 srand((unsigned int)time(&ts)); for (i = 0; i < 10; i++) { arr[i] = (int)(rand() % 100); } //打印数组 printf("\n原始数据----\n"); show(arr, 10); merge_sort(arr, 0, 9); show(arr, 10); } int main(int argc,char*argv[]) { test(); return 0; }
小结
归并排序从我目前的分析来看,大量数据归并排序一定会产生更多的内存碎片。
从开发经验来看,分配大量的小内存,实际上对性能影响也是很大的,产生海量的内存碎片,对于回收也很困难。
通盘分析下来,感觉归并排序这种用内存换性能的交换比并不划算
那么在日常编程中,将尽量减少归并排序的使用,尽量使用快速排序来替代归并排序