排序算法--------归并排序

逃离我推掉我的手 2022-03-20 15:54 495阅读 0赞

归并排序

  • 1.简介
  • 2.图解
  • 3.算法思想
  • 4.Java递归实现
  • 5.算法分析:
  • 6.总结
  • 7.归并排序优化

1.简介

归并排序:是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

归并操作(Merge):也叫归并算法,指的是将两个已经排序的序列合并成一个序列的操作。归并排序算法依赖归并操作。归并排序有多路归并排序、两路归并排序 , 可用于内排序,也可以用于外排序。这里仅对内排序的两路归并方法进行讨论。

2.图解

在这里插入图片描述

3.算法思想

  • 归并排序有两种实现方式: 基于递归的归并排序和基于循环的归并排序。(也叫自顶向下的归并排序自底向上的归并排序
  • 两种实现对于最小集合的归并操作思想是一样的区别在于如何划分数组
  • 分治法将问题分(divide) 成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案”修补”在一起,即分而治之。

4.Java递归实现

  1. package com.lsl.datastructure;
  2. public class MergeSort {
  3. public static void main(String[] args) {
  4. int[] nums = { 5,6,3,1,8,7,2,4};
  5. sort(nums);
  6. for (int num : nums) {
  7. System.out.print(num+" ");
  8. }
  9. }
  10. /** * @param arr 待排序数组 */
  11. public static void sort(int[] arr){
  12. //在排序前,先建好一个长度等于原数组长度的临时数组,避免递归中频繁开辟空间
  13. int [] temp = new int[arr.length];
  14. mergeSort(arr,0,arr.length-1,temp);
  15. }
  16. /** * @param arr 待排序数组 * @param left 起始元素角标 0 * @param right 最后一个元素角标 n -1 * @param temp 临时数组 */
  17. private static void mergeSort(int[] arr, int left, int right,int[] temp) {
  18. //2.递归划分数组
  19. if (left<right) {
  20. //1.开始归并排序 向下取整
  21. int mid = (left + right) / 2;
  22. //左边归并排序,使得左子序列有序
  23. mergeSort(arr, left, mid,temp);
  24. //右边归并排序,使得右子序列有序
  25. mergeSort(arr, mid + 1, right,temp);
  26. //3.将两边的元素归并排序
  27. merge(arr, left, mid, right,temp);
  28. }
  29. }
  30. /** * @param arr 待排序数组 * @param left 分段后的起始元素角标 * @param right 分段后的最后一个元素角标 * @param temp 临时数组 */
  31. private static void merge(int[] arr, int left, int mid, int right,int[] temp) {
  32. //左序列指针
  33. int i = left;
  34. //右序列指针
  35. int j = mid + 1;
  36. //临时数组指针
  37. int t = 0;
  38. while (i<=mid && j<=right){
  39. if(arr[i]<=arr[j]){
  40. temp[t++] = arr[i++];
  41. }else {
  42. temp[t++] = arr[j++];
  43. }
  44. }
  45. //将左边剩余元素填充进temp中
  46. while(i<=mid){
  47. temp[t++] = arr[i++];
  48. }
  49. //将右序列剩余元素填充进temp中
  50. while(j<=right){
  51. temp[t++] = arr[j++];
  52. }
  53. t = 0;
  54. //将temp中的元素全部拷贝到原数组中
  55. while(left <= right){
  56. arr[left++] = temp[t++];
  57. }
  58. }
  59. }

5.算法分析:

(1)稳定性
 归并排序是一种稳定的排序。

(2)存储结构要求
 可用顺序存储结构。也易于在链表上实现。

(3)时间复杂度
 对长度为n的文件,需进行 趟二路归并,每趟归并的时间为O(n),故其时间复杂度无论是在最好情况下还是在最坏情况下均是O(nlgn)

(4)空间复杂度
  需要一个辅助向量来暂存两有序子文件归并的结果,故其辅助空间复杂度为O(n)

6.总结

归并排序是稳定排序,它也是一种十分高效的排序,能利用完全二叉树特性的排序一般性能都不会太差。java中Arrays.sort()采用了一种名为TimSort的排序算法,就是归并排序的优化版本。从本文可看出,每次合并操作的平均时间复杂度为O(n),而完全二叉树的深度为|log2n|。总的平均时间复杂度为O(nlogn)。而且,归并排序的最好,最坏,平均时间复杂度均为O(nlogn)

7.归并排序优化

参考:http://www.cnblogs.com/noKing/p/7940531.html

小结:

  • 当递归到规模足够小时,利用插入排序
  • 归并前判断一下是否还有必要归并
  • 只在排序前开辟一次空间

参考博文:https://www.cnblogs.com/chengxiao/p/6194356.html

版权声明:本博客为记录本人自学感悟,转载需注明出处!
https://me.csdn.net/qq_39657909

发表评论

表情:
评论列表 (有 0 条评论,495人围观)

还没有评论,来说两句吧...

相关阅读

    相关 排序算法——归并排序

    引言 归并排序可以使用递归或迭代的方式来实现,时间复杂度是都是 O(N \ logN)。 归并排序的核心是将待排序数组分组,可以整体二分,也可以设置步长迭代切分。归并排

    相关 排序算法-归并排序

    归并排序也是一个比较快速的排序算法,其思想是运用分治的思想,先对要排序的数进行分,每次从中间分成两部分,然后知道分成最小,然后在把他们合起来,边合起来边排序,最后有序,每次分的

    相关 排序算法——归并排序

    前言 将待排序序列R\[0...n-1\]看成是n个长度为1的有序序列,将相邻的有序表成对归并,得到n/2个长度为2的有序表;将这些有序序列再次归并,得到n/4个长度为4

    相关 排序算法归并排序

    一、前言     归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用 分治法(Divide and Conquer) 的一个非常典型的应用。 --------