当前位置:   article > 正文

归并排序算法(java实现)_java归并排序

java归并排序

基本思想

归并排序是由递归实现的,主要是分而治之的思想,也就是通过将问题分解成多个容易求解的局部性小问题来解开原本的问题的技巧。

归并排序在合并两个已排序数组时,如果遇到了相同的元素,只要保证前半部分数组优先于后半部分数组, 相同元素的顺序就不会颠倒。所以归并排序属于稳定的排序算法

每次分别排左半边和右半边,不断递归调用自己,直到只有一个元素递归结束,开始回溯,调用 merge 函数,合并两个有序序列,再合并的时候每次给末尾追上一个最大 int 这样就不怕最后一位的数字不会被排序。

归并排序的效率是比较高的,设数列长为N,将数列分开成小数列一共要logN步,每步都是一个合并有序数列的过程,时间复杂度可以记为O(N),故一共为O(N log N)。因为归并排序每次都是在相邻的数据中进行操作,所以归并排序在O(N*logN)的几种排序方法(快速排序,归并排序,希尔排序,堆排序)也是效率比较高的。

排序过程

 

算法流程:

1、将一个数组拆分为两个,从中间点拆开,通过递归操作来实现一层一层拆分。

2、从左右数组中选择小的元素放入到临时空间,并移动下标到下一位置。

3、重复步骤2直到某一下标达到尾部。

4、将另一序列剩下的所有元素依次放入临时空间。

5、将临时空间的数据依次放入原数据数组。

基础代码

  1. package Sort;
  2. //针对 一个数组 左右两部分已经排好序
  3. public class 归并排序基础 {
  4. public static void main(String[] args) {
  5. int[] arr = {1,4,7,8,3,6,9};
  6. merge(arr);
  7. }
  8. // 把数组arr = {1,4,7,8,3,6,9} 分成两部分 分别为1,4,7,83,6,9
  9. static void merge(int[] arr) {
  10. int mid = arr.length / 2;
  11. int[] temp = new int[arr.length];
  12. int i = 0; //i是数组arr前部分的第一位
  13. int j = mid+1; //j是数组arr后部分的第一位
  14. int k = 0; //k是 新数组temp的第一位
  15. //当 arr数组两边都还有数 时
  16. while (i <= mid && j < arr.length) {
  17. if (arr[i] <= arr[j]) {
  18. temp[k] = arr[i];
  19. i++;
  20. k++;
  21. } else {
  22. temp[k] = arr[j];
  23. j++;
  24. k++;
  25. }
  26. }
  27. //将右边剩余的归并
  28. while (i <= mid) {
  29. temp[k++] = arr[i++];
  30. }
  31. //将左边剩余的归并
  32. while (j < arr.length) {
  33. temp[k++] = arr[j++];
  34. }
  35. print(temp);
  36. }
  37. //排序
  38. static void swap(int[] arr,int i,int j) {
  39. int temp = arr[i];
  40. arr[i] = arr[j];
  41. arr[j] = temp;
  42. }
  43. //打印
  44. static void print(int[] arr) {
  45. for (int i = 0; i < arr.length; i++) {
  46. System.out.print(arr[i] + " ");
  47. }
  48. }
  49. }

加入归并的代码

  1. package Sort;
  2. public class 归并排序递归 {
  3. public static void main(String[] args) {
  4. // int[] arr = {1,4,7,8,3,6,9};
  5. int[] arr = {3,0,6,4,1,3,7,8,5,9};
  6. sort(arr,0,arr.length-1);
  7. print(arr);
  8. }
  9. public static void sort(int[] arr,int left,int right) {
  10. if (left == right) {
  11. return;
  12. }
  13. //分成两半
  14. int mid = left +(right-left)/2;
  15. //左边排序
  16. sort(arr, left, mid);
  17. //右边排序
  18. sort(arr, mid +1, right);
  19. merge(arr, left, mid+1, right);
  20. }
  21. //leftPtr 指数组最左边
  22. //rightPtr 指数组中间
  23. //rightBound 数组最右边
  24. static void merge(int[] arr,int leftPtr,int rightPtr,int rightBound) {
  25. int mid = rightPtr - 1;
  26. int[] temp = new int[rightBound - leftPtr + 1];
  27. int i = leftPtr;
  28. int j = rightPtr;
  29. int k = 0;
  30. while (i <= mid && j <= rightBound) {
  31. if (arr[i] <= arr[j]) {
  32. temp[k] = arr[i];
  33. i++;
  34. k++;
  35. } else {
  36. temp[k] = arr[j];
  37. j++;
  38. k++;
  39. }
  40. }
  41. // 将右边剩余的归并
  42. while (i <= mid) {
  43. temp[k++] = arr[i++];
  44. }
  45. //将左边剩余的归并
  46. while (j <= rightBound) {
  47. temp[k++] = arr[j++];
  48. }
  49. for(int m = 0; m < temp.length;m++) arr[leftPtr+m] = temp[m];
  50. }
  51. //排序
  52. static void swap(int[] arr,int i,int j) {
  53. int temp = arr[i];
  54. arr[i] = arr[j];
  55. arr[j] = temp;
  56. }
  57. //打印
  58. static void print(int[] arr) {
  59. for (int i = 0; i < arr.length; i++) {
  60. System.out.print(arr[i] + " ");
  61. }
  62. }
  63. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/67007
推荐阅读
相关标签
  

闽ICP备14008679号