• 归并排序(java)


    大家好我是苏麟 , 今天说说归并排序

    归并排序

    递归

    正式学习归并排序之前,我们得先学习一下递归算法

    定义:

    定义方法时,在方法内部调用方法本身,称之为递归.

    1. public void show(){
    2. System.out.println("aaaa");
    3. show();
    4. }

    作用:

    它通常把一个大型复杂的问题,层层转换为一个与原问题相似的,规模较小的问题来求解。递归策略只需要少量的 程序就可以描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。

    注意事项:

    在递归中,不能无限制的调用自己,必须要有边界条件,能够让递归结束,因为每一次递归调用都会在栈内存开辟 新的空间,重新执行方法,如果递归的层级太深,很容易造成栈内存溢出。

    需求:

    请定义一个方法,使用递归完成求N的阶乘

    1. 分析:
    2. 1!: 1
    3. 2!: 2*1=2*1!
    4. 3!: 3*2*1=3*2!
    5. 4!: 4*3*2*1=4*3!
    6. ...
    7. n!: n*(n-1)*(n-2)...*2*1=n*(n-1)!
    8. 所以,假设有一个方法factorial(n)用来求n的阶乘,那么n的阶乘还可以表示为n*factorial(n-1)

    代码实现:

    1. public class Test {
    2. public static void main(String[] args) throws Exception {
    3. int result = factorial(5);
    4. System.out.println(result);
    5. }
    6. public static int factorial(int n){
    7. if (n==1){
    8. return 1;
    9. }
    10. return n*factorial(n-1);
    11. }
    12. }

    归并排序

    归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。将已有序的子 序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序 表,称为二路归并。

    需求:

    排序前:{8,4,5,7,1,3,6,2} 排序后:{1,2,3,4,5,6,7,8}

    排序原理:

    1.尽可能的一组数据拆分成两个元素相等的子组,并对每一个子组继续拆分,直到拆分后的每个子组的元素个数是 1为止。

    2.将相邻的两个子组进行合并成一个有序的大组;

    3.不断的重复步骤2,直到最终只有一个组为止。

    代码 :

    1. package src.sl.sort;
    2. /**
    3. * 归并排序
    4. * 数据类型 : int
    5. */
    6. public class MergeSort {
    7. //辅助数组
    8. public static int[] assist;
    9. public static void main(String[] args) {
    10. int[] arr = new int[]{2,5,6,1,3,2,4,8,6,7,5};
    11. sort(arr);
    12. for (int i = 0; i < arr.length; i++) {
    13. System.out.print(arr[i] + " ");
    14. }
    15. }
    16. /**
    17. * 对数组全部排序
    18. *
    19. * @param arr
    20. */
    21. public static void sort(int[] arr) {
    22. assist = new int[arr.length];
    23. int left = 0;
    24. int right = arr.length-1;
    25. sort(arr, left, right);
    26. }
    27. /**
    28. * 对数组部分排序
    29. *
    30. * @param arr
    31. * @param left
    32. * @param right
    33. */
    34. public static void sort(int[] arr, int left, int right) {
    35. if (left >= right) {
    36. return;
    37. }
    38. int mid = left + (right-left) / 2;
    39. sort(arr, left, mid);
    40. sort(arr,mid + 1,right);
    41. //归并
    42. merge(arr, left, mid, right);
    43. }
    44. /**
    45. * 归并
    46. *
    47. * @param arr
    48. * @param left
    49. * @param mid
    50. * @param right
    51. */
    52. public static void merge(int[] arr, int left, int mid, int right) {
    53. int i = left;
    54. int p1 = left;
    55. int p2 = mid + 1;
    56. while (p1 <= mid && p2 <= right){
    57. if (arr[p1] < arr[p2]){
    58. assist[i++] = arr[p1++];
    59. }else {
    60. assist[i++] = arr[p2++];
    61. }
    62. }
    63. while (p1 <= mid){
    64. assist[i++] = arr[p1++];
    65. }
    66. while (p2 <= right){
    67. assist[i++] = arr[p2++];
    68. }
    69. for (int j = left; j<=right;j++){
    70. arr[j] = assist[j];
    71. }
    72. }
    73. }

    这期就到这里 , 下期见!

  • 相关阅读:
    linux 性能优化
    解决传统难题,WMS系统实现信息数据实时追踪
    暑假总结-集成ip2region实现离线IP地址定位
    ElasticSearch7.3学习(二十六)----搜索(Search)参数总结、结果跳跃(bouncing results)问题解析
    jenkins实践篇(1)——基于分支的自动发布
    5.1 内存CRC32完整性检测
    From Java To Kotlin:空安全、扩展、函数、Lambda很详细,这次终于懂了
    ORACLE归档日志满,没法访问
    用案例告诉你,数据库的备份还原如此简单!!!
    scss 使用变量名注意事项
  • 原文地址:https://blog.csdn.net/sytdsqzr/article/details/134082271