算法 排序算法之归并排序
2017-06-03 22:40
309 查看
归并排序
归并排序主要是二路归并排序基本思想
设数组a中存放了n个数据元素初始时把它们看成n个长度为1的有序子数组,然后从第一个子数组开始,把相邻子数组两两合并,得到n/2的整数上界个长度为2的新的有序子数组(当n为奇数时最后一个新的有序子数组的长度为1)
对这些新的有序子数组再两两合并,直到最后长度为n的有序数组位置
排序过程
以数组{50,10,90,30,70,40,80,60,20}为例
代码实现
void Merge(DataType a[], int n, DataType swap[], int k) { /*k为有序子数组的长度,一次二路归并排序后的有序子序列放在数组swap中*/ int m = 0, u1, l2, i, j, u2; /*第一个有序子数组下界为0*/ int l1 = 0; while (l1 + k <= n - 1) { l2 = l1 + k;//计算第二个有序子数组下界 u1 = l2 - 1;//计算第一个有序子数组上界 u2 = (l2 + k - 1 <= n - 1) ? l2 + k - 1 : n - 1;//计算第二个有序子数组上界 /*两个有序子数组合并*/ for (i = l1, j = l2; i <= u1 && j <= u2; m++) { if (a[i] <= a[j]) { swap[m] = a[i]; i++; } else { swap[m] = a[j]; j++; } } /*子数组2已归并完,将数组1中剩余的元素放到数组swap中*/ while (i <= u1) { swap[m] = a[i]; m++; i++; } /*子数组1已归并完,将数组2中剩余的元素放到数组swap中*/ while (j <= u2) { swap[m] = a[j]; m++; j++; } l1 = u2 + 1; } /*将原始数组中只够一组的元素顺序放到数组swap中*/ for (i = l1; i < n; i++, m++) { swap[m] = a[i]; } }
void MergeSort(DataType a[], int n) { int i, k = 1;//归并长度从1开始 DataType * swap; swap = (DataType *) malloc(sizeof(DataType) * n); while (k < n) { Merge(a, n, swap, k); for (i = 0; i < n; i++) { a[i] = swap[i]; } k = 2 * k; } free(swap); }
java实现
public static void mergeSort(int[] arr) { mergeSort(arr, 0, arr.length - 1); } private static void mergeSort(int[] arr, int low, int high) { int mid = (low + high) / 2; if (low < high) { //左边 mergeSort(arr, low, mid); //右边 mergeSort(arr, mid + 1, high); //左右归并 merge(arr, low, mid, high); } } private static void merge(int[] arr, int low, int mid, int high) { int[] temp = new int[high - low + 1]; int left = low;//左指针 int right = mid + 1;//右指针 int k = 0; //把较小的数先移动到新数组中 while (left <= mid && right <= high) { if (arr[left] < arr[right]) { temp[k++] = arr[left++]; } else { temp[k++] = arr[right++]; } } //把左边剩余的数移入数组 while (left <= mid) { temp[k++] = arr[left++]; } //把右边剩余的数移入数组 while (right <= high) { temp[k++] = arr[right++]; } //把新数组中的数覆盖nums数组 for (int k2 = 0; k2 < temp.length; k2++) { arr[k2 + low] = temp[k2]; } }
算法分析
时间复杂度一次二路归并排序归并的次数log2n 每次比较次数n-1 故时间复杂度是O(nlog2n)
空间复杂度
使用了n个临时内存单元存放数据 空间复杂度O(n)
稳定性
归并排序是一种比较占内存,但却效率高且稳定的算法
相关文章推荐
- 算法系列(四)排序算法中篇--归并排序和快速排序
- 笔试面试最常涉及到的12种排序算法(包括插入排序、二分插入排序、希尔排序、选择排序、冒泡排序、鸡尾酒排序、快速排序、堆排序、归并排序、桶排序、计数排序和基数排序)进行了详解。每一种算法都有基本介绍、算
- 算法 排序算法之归并排序 java实现
- 【算法】排序算法第四讲:归并排序
- 算法—归并排序改良后亿级秒排及排序算法的极致
- 【图解算法】排序算法——归并排序
- 算法系列(四)排序算法中篇--归并排序和快速排序
- 常用算法之排序算法四【归并排序】
- 常用算法--基本排序算法(冒泡排序,选择排序,插入排序,快速排序,归并排序,桶排序)
- 【算法】排序算法(三)——归并排序
- [算法]-高级排序算法-归并排序
- 算法分析中最常用的几种排序算法(插入排序、希尔排序、冒泡排序、选择排序、快速排序,归并排序)C 语言版
- 算法学习一之常见的七大排序算法
- 经典算法-C#四种排序算法
- 【排序算法】归并排序
- 算法_基本排序算法之冒泡排序,选择排序,插入排序和希尔排序
- 算法复习——归并排序
- 【转】排序算法复习(Java实现) (二): 归并排序,堆排序,桶式排序,基数排序
- 排序算法之 归并排序 及其时间复杂度和空间复杂度
- 算法导论——排序算法