归并排序(Mergesort)之Java实现

本文详细介绍了一种经典的排序算法——归并排序。归并排序是一种典型的分治算法,它将数组分成两个子数组进行排序,然后合并成有序数组。文章不仅阐述了归并排序的基本原理,还提供了详细的Java实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


目录(?)[+]

归并排序算法介绍

归并排序是一个分治算法(Divide and Conquer)的一个典型实例,把一个数组分为两个大小相近(最多差一个)的子数组,分别把子数组都排好序之后通过归并(Merge)手法合成一个大的排好序的数组,归并的过程依然用扑克来解释,想象一下桌子上有两堆排好序(从小到大)的牌,每一次从两堆里面各抽取一张,比较一下两张的大小,如果两张一样大,都取出放到目标数组,否则取出较小的放到目标数组,另外一个放回原堆里面。归并排序需要额外的空间来存储临时数据,不过它的最坏运行时间都是O(nlogn)

归并排序算法Java实现

如《插入排序(Insertsort)之Java实现》一样,先实现一个数组工具类。代码如下:

  1. publicclassArrayUtils{
  2. publicstaticvoidprintArray(int[]array){
  3. System.out.print("{");
  4. for(inti=0;i<array.length;i++){
  5. System.out.print(array[i]);
  6. if(i<array.length-1){
  7. System.out.print(",");
  8. }
  9. }
  10. System.out.println("}");
  11. }
  12. }

归并排序为分治法,体现在把一个数组分为基本等长的两个子数组,重复这个过程,直到两个子数组都只有一个元素,归并的过程是算法的核心,前面已经提到过。归并排序的Java实现以及测试代码如下:

  1. publicclassMergeSort{
  2. publicstaticvoidmain(String[]args){
  3. int[]array={9,8,7,6,5,4,3,2,1,0,-1,-2,-3};
  4. System.out.println("Beforesort:");
  5. ArrayUtils.printArray(array);
  6. mergeSort(array);
  7. System.out.println("Aftersort:");
  8. ArrayUtils.printArray(array);
  9. }
  10. publicstaticvoidmergeSort(int[]array){
  11. sortArray(array,0,array.length-1);
  12. }
  13. privatestaticvoidsortArray(int[]array,intstart,intend){
  14. //单个元素不需要排序,直接返回
  15. if(start==end){
  16. return;
  17. }
  18. intsortSize=end-start+1;
  19. intseperate;
  20. if(sortSize%2==0){
  21. seperate=start+sortSize/2-1;
  22. }else{
  23. seperate=start+sortSize/2;
  24. }
  25. sortArray(array,start,seperate);
  26. sortArray(array,seperate+1,end);
  27. mergeArray(array,start,seperate,end);
  28. }
  29. privatestaticvoidmergeArray(int[]array,intstart,intseperate,intend){
  30. inttotalSize=end-start+1;
  31. intsize1=seperate-start+1;
  32. intsize2=end-seperate;
  33. int[]array1=newint[size1];
  34. int[]array2=newint[size2];
  35. for(inti=0;i<size1;i++){
  36. array1[i]=array[start+i];
  37. }
  38. for(inti=0;i<size2;i++){
  39. array2[i]=array[seperate+1+i];
  40. }
  41. intmergeCount=0;
  42. intindex1=0;
  43. intindex2=0;
  44. while(mergeCount<totalSize){
  45. //先检查有没有其中的一个数组已经处理完
  46. if(index1==size1){
  47. for(inti=index2;i<size2;i++){
  48. array[start+mergeCount]=array2[i];
  49. mergeCount++;
  50. index2++;
  51. }
  52. }elseif(index2==size2){
  53. for(inti=index1;i<size1;i++){
  54. array[start+mergeCount]=array1[i];
  55. mergeCount++;
  56. index1++;
  57. }
  58. }else{
  59. intvalue1=array1[index1];
  60. intvalue2=array2[index2];
  61. if(value1==value2){
  62. array[start+mergeCount]=value1;
  63. array[start+mergeCount+1]=value1;
  64. mergeCount+=2;
  65. index1++;
  66. index2++;
  67. }elseif(value1<value2){
  68. array[start+mergeCount]=value1;
  69. mergeCount++;
  70. index1++;
  71. }elseif(value1>value2){
  72. array[start+mergeCount]=value2;
  73. mergeCount++;
  74. index2++;
  75. }
  76. }
  77. }
  78. }
  79. }

归并排序算法介绍

归并排序是一个分治算法(Divide and Conquer)的一个典型实例,把一个数组分为两个大小相近(最多差一个)的子数组,分别把子数组都排好序之后通过归并(Merge)手法合成一个大的排好序的数组,归并的过程依然用扑克来解释,想象一下桌子上有两堆排好序(从小到大)的牌,每一次从两堆里面各抽取一张,比较一下两张的大小,如果两张一样大,都取出放到目标数组,否则取出较小的放到目标数组,另外一个放回原堆里面。归并排序需要额外的空间来存储临时数据,不过它的最坏运行时间都是O(nlogn)

归并排序算法Java实现

如《插入排序(Insertsort)之Java实现》一样,先实现一个数组工具类。代码如下:

  1. publicclassArrayUtils{
  2. publicstaticvoidprintArray(int[]array){
  3. System.out.print("{");
  4. for(inti=0;i<array.length;i++){
  5. System.out.print(array[i]);
  6. if(i<array.length-1){
  7. System.out.print(",");
  8. }
  9. }
  10. System.out.println("}");
  11. }
  12. }

归并排序为分治法,体现在把一个数组分为基本等长的两个子数组,重复这个过程,直到两个子数组都只有一个元素,归并的过程是算法的核心,前面已经提到过。归并排序的Java实现以及测试代码如下:

  1. publicclassMergeSort{
  2. publicstaticvoidmain(String[]args){
  3. int[]array={9,8,7,6,5,4,3,2,1,0,-1,-2,-3};
  4. System.out.println("Beforesort:");
  5. ArrayUtils.printArray(array);
  6. mergeSort(array);
  7. System.out.println("Aftersort:");
  8. ArrayUtils.printArray(array);
  9. }
  10. publicstaticvoidmergeSort(int[]array){
  11. sortArray(array,0,array.length-1);
  12. }
  13. privatestaticvoidsortArray(int[]array,intstart,intend){
  14. //单个元素不需要排序,直接返回
  15. if(start==end){
  16. return;
  17. }
  18. intsortSize=end-start+1;
  19. intseperate;
  20. if(sortSize%2==0){
  21. seperate=start+sortSize/2-1;
  22. }else{
  23. seperate=start+sortSize/2;
  24. }
  25. sortArray(array,start,seperate);
  26. sortArray(array,seperate+1,end);
  27. mergeArray(array,start,seperate,end);
  28. }
  29. privatestaticvoidmergeArray(int[]array,intstart,intseperate,intend){
  30. inttotalSize=end-start+1;
  31. intsize1=seperate-start+1;
  32. intsize2=end-seperate;
  33. int[]array1=newint[size1];
  34. int[]array2=newint[size2];
  35. for(inti=0;i<size1;i++){
  36. array1[i]=array[start+i];
  37. }
  38. for(inti=0;i<size2;i++){
  39. array2[i]=array[seperate+1+i];
  40. }
  41. intmergeCount=0;
  42. intindex1=0;
  43. intindex2=0;
  44. while(mergeCount<totalSize){
  45. //先检查有没有其中的一个数组已经处理完
  46. if(index1==size1){
  47. for(inti=index2;i<size2;i++){
  48. array[start+mergeCount]=array2[i];
  49. mergeCount++;
  50. index2++;
  51. }
  52. }elseif(index2==size2){
  53. for(inti=index1;i<size1;i++){
  54. array[start+mergeCount]=array1[i];
  55. mergeCount++;
  56. index1++;
  57. }
  58. }else{
  59. intvalue1=array1[index1];
  60. intvalue2=array2[index2];
  61. if(value1==value2){
  62. array[start+mergeCount]=value1;
  63. array[start+mergeCount+1]=value1;
  64. mergeCount+=2;
  65. index1++;
  66. index2++;
  67. }elseif(value1<value2){
  68. array[start+mergeCount]=value1;
  69. mergeCount++;
  70. index1++;
  71. }elseif(value1>value2){
  72. array[start+mergeCount]=value2;
  73. mergeCount++;
  74. index2++;
  75. }
  76. }
  77. }
  78. }
  79. }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值