各种排序算法【持续更新中.....】

1.归并排序

归并排序 ,归并排序是采用分治法(Divide and Conquer)的一个非常典型的应用,所以我们先来说一下什么是分治法。

分治法

定义

分治(英语:Divide and Conquer),字面上的解释是「分而治之」,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。

过程

分治算法的核心思想就是「分而治之」。

大概的流程可以分为三步:分解 -> 解决 -> 合并。

  1. 分解原问题为结构相同的子问题。
  2. 分解到某个容易求解的边界之后,进行递归求解。
  3. 将子问题的解合并成原问题的解。

分治法能解决的问题一般有如下特征:

  • 该问题的规模缩小到一定的程度就可以容易地解决。
  • 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质,利用该问题分解出的子问题的解可以合并为该问题的解。
  • 该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。

参考链接:

递归 & 分治 - OI Wiki (oi-wiki.org)

了解清楚分治法后,我们来看归并排序

归并排序

merge

归并排序最核心的部分是合并(merge)过程:将两个有序的数组 a[i]b[j] 合并为一个有序数组 c[k]

从左往右枚举 a[i]b[j],找出最小的值并放入数组 c[k];重复上述过程直到 a[i]b[j] 有一个为空时,将另一个数组剩下的元素放入 c[k]

java 复制代码
import  java.util.*;

public class MergeSort {
    public static void main(String[] args) {
        int[] a = {3, 4, 5};
        int[] b = {1, 2};
        System.out.println("合并后的数组: " + Arrays.toString(merge(a, b)));
    }

    public static int[] merge(int[] a, int[] b) {
        int i = 0, j = 0;
        int[] c = new int[a.length + b.length];

        while (i < a.length && j < b.length) {
            // 数组b比a小
            if (b[j] < a[i]) {
                // 将b[j]添加到c中,并增加j ,一定不能写成++j
                c[i + j] = b[j++];
            } else {
                c[i + j] = a[i++];
            }
        }

        // b数组遍历完了,将a数组中剩余元素添加到c中
        while (i < a.length) {
            c[i + j] = a[i++];
        }
        // a 数组遍历完了,将b数组中剩余的元素添加到c中
        while (j < b.length) {
            c[i + j] = b[j++];
        }

        return c;
    }
}

分治法

  1. 当数组长度为 为1 时,该数组就已经是有序的,不用再分解。

  2. 当数组长度大于 1 时,该数组很可能不是有序的。此时将该数组分为两段,再分别检查两个数组是否有序(用第 1 条)。如果有序,则将它们合并为一个有序数组;否则对不有序的数组重复第 2 条,再合并。

整个流程见下图

java 复制代码
    public static int[] mergeSort(int[] arr) {
        if (arr.length <= 1) {
            return arr;
        }

        int middle = arr.length / 2;
        // 取原本数组的一个副本,左半部分
        int[] left = Arrays.copyOfRange(arr, 0, middle);
        // 取原本数组的一个副本,右半部分
        int[] right = Arrays.copyOfRange(arr, middle, arr.length);

        left = mergeSort(left);
        right = mergeSort(right);

        return merge(left, right);
    }

整体代码

整个归并排序的代码如下

java 复制代码
package mbb;

import java.util.Arrays;

public class MergeSortExample {

    // 归并两个数组的辅助方法
    public static int[] merge(int[] left, int[] right) {
        int[] result = new int[left.length + right.length];
        int i = 0, j = 0, k = 0;

        while (i < left.length && j < right.length) {
            if (left[i] <= right[j]) {
                result[k++] = left[i++];
            } else {
                result[k++] = right[j++];
            }
        }

        // 将剩余的元素拷贝到结果数组
        while (i < left.length) {
            result[k++] = left[i++];
        }
        while (j < right.length) {
            result[k++] = right[j++];
        }

        return result;
    }

    // 归并排序的主要方法
    public static int[] mergeSort(int[] arr) {
        if (arr.length <= 1) {
            return arr;
        }

        int middle = arr.length / 2;
        // 取原本数组的一个副本,左半部分
        int[] left = Arrays.copyOfRange(arr, 0, middle);
        // 取原本数组的一个副本,右半部分
        int[] right = Arrays.copyOfRange(arr, middle, arr.length);

        left = mergeSort(left);
        right = mergeSort(right);

        return merge(left, right);
    }

    // 主函数,用于演示归并排序
    public static void main(String[] args) {
        int[] arr = {34, 7, 23, 32, 5, 62};
        System.out.println("Original array: " + Arrays.toString(arr));

        int[] sortedArr = mergeSort(arr);
        System.out.println("Sorted array: " + Arrays.toString(sortedArr));
    }
}

不懂的强烈建议看下面三个链接

排序算法:归并排序【图解+代码】_哔哩哔哩_bilibili

归并排序 - OI Wiki (oi-wiki.org)

图解归并排序,带你彻底了解清楚!_归并排序算法过程图解-CSDN博客

冒泡排序

冒泡排序的思想非常简单

  1. 比较相邻的元素。如果第一个比第二个大(小),就交换他们两个。

  2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大(小)的数。

  3. 针对所有的元素重复以上的步骤,除了最后已经选出的元素(有序)。

  4. 持续每次对越来越少的元素(无序元素)重复上面的步骤,直到没有任何一对数字需要比较,则序列最终有序。

java 复制代码
public class BubbleSortExample {

    public static void main(String[] args) {
        int[] array = {64, 34, 25, 12, 22, 11, 90};
        bubbleSort(array);
        
        System.out.println("Sorted array:");
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i] + " ");
        }
    }

    public static void bubbleSort(int[] array) {
        for (int i = 0; i < array.length - 1; i++) {
            for (int j = 0; j < array.length - 1 - i; j++) {
                if (array[j] > array[j + 1]) {
                    // 交换array[j]和array[j+1]
                    int temp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = temp;
                }
            }
        }
    }
}
相关推荐
人生在勤,不索何获-白大侠14 分钟前
day17——Java集合进阶(Collections、Map)
java·开发语言
程序员小羊!26 分钟前
Java教程:JavaWeb ---MySQL高级
java·开发语言·mysql
白仑色33 分钟前
Spring Boot 多环境配置详解
java·spring boot·后端·微服务架构·配置管理
超级小忍35 分钟前
在 Spring Boot 中优化长轮询(Long Polling)连接频繁建立销毁问题
java·spring boot·后端
David爱编程39 分钟前
Java 中 Integer 为什么不是万能的 int 替代品?
java·后端
老马啸西风41 分钟前
个人网站一键引入免费开关评论功能 giscus
java
科大饭桶1 小时前
数据结构自学Day5--链表知识总结
数据结构·算法·leetcode·链表·c
Z_W_H_1 小时前
【springboot】IDEA手动创建SpringBoot简单工程(无插件)
java·spring boot·intellij-idea
HeXDev1 小时前
【SkyWalking】服务端部署与微服务无侵入接入实战指南
java·微服务·架构·skywalking·链路追踪·微服务治理
探索java1 小时前
Java 深入解析:JVM对象创建与内存机制全景图
java·jvm