首页 > 编程语言 >Java 经典排序算法代码 + 注释分析(冒泡、选择、插入、希尔、快排、计数、堆排、归并)

Java 经典排序算法代码 + 注释分析(冒泡、选择、插入、希尔、快排、计数、堆排、归并)

时间:2024-07-22 21:00:08浏览次数:17  
标签:堆排 right Java nums int ++ 快排 length left

Java 经典排序算法代码 + 注释分析(冒泡、选择、插入、希尔、快排、计数、堆排、归并)



以下是八种经典排序算法的代码,Java8亲测可用,可以直接运行
import java.util.Arrays;

public class Sort {

    private static final int[] nums = {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48};

    public static void main(String[] args) {

        int num = 7;

        switch (num) {

            case 0:
                bubbleSort();

            case 1:
                selectionSort();

            case 2:
                insertionSort();

            case 3:
                shellSort();

            case 4:
                quickSort(0, nums.length - 1);

            case 5:
                countSort();

            case 6:
                heapSort();

            case 7:
                mergeSort();

        }

    }

    /**
     * 冒泡排序
     * <p>
     * 稳定性:稳定
     * <p>
     * 时间复杂度:最佳:O(n),最差:O(n^2),平均:O(n^2)
     * <p>
     * 空间复杂度:O(1)
     */
    private static void bubbleSort() {

        for (int i = 1; i < nums.length; i++) {

            boolean flag = true;

            for (int j = 0; j < nums.length - i; j++) {

                if (nums[j] > nums[j + 1]) {

                    nums[j] ^= nums[j + 1];
                    nums[j + 1] ^= nums[j];
                    nums[j] ^= nums[j + 1];

                    flag = false;

                }

            }

            if (flag) {
                break;
            }

        }

        System.out.println(Arrays.toString(nums));

    }

    /**
     * 选择排序
     * <p>
     * 稳定性:不稳定
     * <p>
     * 时间复杂度:最佳:O(n^2),最差:O(n^2),平均:O(n^2)
     * <p>
     * 空间复杂度:O(1)
     */
    private static void selectionSort() {

        for (int i = 0; i < nums.length; i++) {

            int minIndex = i;

            for (int j = i + 1; j < nums.length; j++) {

                if (nums[minIndex] > nums[j]) {
                    minIndex = j;
                }

            }

            if (minIndex != i) {
                nums[i] ^= nums[minIndex];
                nums[minIndex] ^= nums[i];
                nums[i] ^= nums[minIndex];
            }

        }

        System.out.println(Arrays.toString(nums));

    }

    /**
     * 插入排序
     * <p>
     * 稳定性:稳定
     * <p>
     * 时间复杂度:最佳:O(n),最差:O(n^2),平均:O(n^2)
     * <p>
     * 空间复杂度:O(1)
     */
    private static void insertionSort() {

        for (int i = 1; i < nums.length; i++) {

            int preIndex = i - 1;
            int current = nums[i];

            while (preIndex >= 0 && current < nums[preIndex]) {
                nums[preIndex + 1] = nums[preIndex];
                preIndex--;
            }

            nums[preIndex + 1] = current;

        }

        System.out.println(Arrays.toString(nums));

    }

    /**
     * 希尔排序
     * <p>
     * 稳定性:不稳定
     * <p>
     * 时间复杂度:最佳:O(nlogn),最差:O(n^2),平均:O(nlogn)
     * <p>
     * 空间复杂度:O(1)
     */
    private static void shellSort() {

        int gap = nums.length / 2;

        while (gap > 0) {

            for (int i = gap; i < nums.length; i++) {

                int current = nums[i];
                int preIndex = i - gap;

                while (preIndex >= 0 && current < nums[preIndex]) {

                    nums[preIndex + gap] = nums[preIndex];
                    preIndex -= gap;

                }

                nums[preIndex + gap] = current;

            }

            gap /= 2;

        }

        System.out.println(Arrays.toString(nums));

    }

    /**
     * 快速排序
     * <p>
     * 稳定性:不稳定
     * <p>
     * 时间复杂度:最佳:O(nlogn),最差:O(n^2),平均:O(nlogn)
     * <p>
     * 空间复杂度:O(logn)
     */
    private static void quickSort(int left, int right) {

        if (left <= right) {

            int middle = partition(left, right);
            quickSort(left, middle - 1);
            quickSort(middle + 1, right);

        }

    }

    private static int partition(int left, int right) {

        int pivot = nums[right];
        int pointer = left;

        for (int i = left; i <= right - 1; i++) {

            if (nums[i] <= pivot) {

                int temp = nums[i];
                nums[i] = nums[pointer];
                nums[pointer] = temp;

                pointer++;

            }

        }

        nums[right] = nums[pointer];
        nums[pointer] = pivot;

        System.out.println(Arrays.toString(nums));

        return pointer;

    }

    /**
     * 计数排序
     * <p>
     * 稳定性:稳定
     * <p>
     * 时间复杂度:最佳:O(n+k),最差:O(n+k),平均:O(n+k)
     * <p>
     * 空间复杂度:O(k)
     */
    private static void countSort() {

        int[] MaxMin = findMaxMin();
        int max = MaxMin[0];
        int min = MaxMin[1];

        int[] counts = new int[max - min + 1];
        int[] result = new int[nums.length];

        //计数
        for (int num : nums) {
            counts[num - min]++;
        }

        //累加
        for (int i = 1; i < counts.length; i++) {
            counts[i] += counts[i - 1];
        }

        //排序
        for (int i = nums.length - 1; i >= 0; i--) {
            result[counts[nums[i] - min] - 1] = nums[i];
            counts[nums[i] - min]--;
        }

        System.out.println(Arrays.toString(result));

    }

    private static int[] findMaxMin() {

        int max = Integer.MIN_VALUE;
        int min = Integer.MAX_VALUE;

        for (int num : nums) {
            if (num > max) {
                max = num;
            }
            if (num < min) {
                min = num;
            }
        }

        return new int[]{max, min};

    }

    /**
     * 堆排序
     * <p>
     * 稳定性:不稳定
     * <p>
     * 时间复杂度:最佳:O(nlogn),最差:O(nlogn),平均:O(nlogn)
     * <p>
     * 空间复杂度:O(1)
     */
    private static void heapSort() {

        int index = 0;

        //建堆
        for (index = (nums.length - 1 - 1) / 2; index >= 0; index--) {
            heapify(nums.length, index);
        }

        //排序
        for (int i = nums.length - 1; i > 0; i--) {

            int temp = nums[i];
            nums[i] = nums[0];
            nums[0] = temp;

            heapify(i, 0);

        }

        System.out.println(Arrays.toString(nums));

    }

    //维护堆的性质
    private static void heapify(int length, int index) {

        int largest = index;
        int left = 2 * index + 1;
        int right = 2 * index + 2;

        if (left < length && nums[left] > nums[largest]) {
            largest = left;
        }

        if (right < length && nums[right] > nums[largest]) {
            largest = right;
        }

        if (largest != index) {
            int temp = nums[largest];
            nums[largest] = nums[index];
            nums[index] = temp;

            heapify(length, largest);
        }

    }

    /**
     * 归并排序
     * <p>
     * 稳定性:稳定
     * <p>
     * 时间复杂度:最佳:O(nlogn),最差:O(nlogn),平均:O(nlogn)
     * <p>
     * 空间复杂度:O(n)
     */
    private static void mergeSort() {

        //分配一个辅助数组
        int[] tempArr = new int[nums.length];

        msort(tempArr, 0, nums.length - 1);

        System.out.println(Arrays.toString(nums));

    }

    //归并排序
    private static void msort(int[] tempArr, int left, int right) {

        //如果只有一个元素,就不需要划分
        if (left < right) {

            //找中间点
            int middle = left + (right - left) / 2;

            //划分左半区
            msort(tempArr, left, middle);
            //划分右半区
            msort(tempArr, middle + 1, right);

            //合并
            merge(tempArr, left, middle, right);

        }

    }

    //合并
    private static void merge(int[] tempArr, int left, int middle, int right) {

        //左半区第一个元素
        int leftPtr = left;

        //右半区第一个元素
        int rightPtr = middle + 1;

        //临时数组元素的下标
        int ptr = left;

        //合并
        while (leftPtr <= middle && rightPtr <= right) {
            if (nums[leftPtr] <= nums[rightPtr]) {
                tempArr[ptr] = nums[leftPtr];
                leftPtr++;
            } else {
                tempArr[ptr] = nums[rightPtr];
                rightPtr++;
            }
            ptr++;
        }

        //左边剩下了
        while (leftPtr <= middle) {
            tempArr[ptr] = nums[leftPtr];
            leftPtr++;
            ptr++;
        }

        //右边剩下了
        while (rightPtr <= right) {
            tempArr[ptr] = nums[rightPtr];
            rightPtr++;
            ptr++;
        }

        //复制回原来的数组
        while (left <= right) {
            nums[left] = tempArr[left];
            left++;
        }

    }

}

标签:堆排,right,Java,nums,int,++,快排,length,left
From: https://blog.csdn.net/XRT_knives/article/details/140619451

相关文章

  • java毕业设计-基于springboot+vue的校园二手交易系统,基于java的校园二手交易系统,基于j
    文章目录前言演示视频项目背景项目架构和内容获取(文末获取)具体实现截图前台功能管理后台技术栈具体功能模块设计系统需求分析可行性分析系统测试为什么我?关于我我自己的网站前言博主介绍:✌️码农一枚,专注于大学生项目实战开发、讲解和毕业......
  • Multithreading in Java
    Whatismultithread?multithread(多线程)可以让程序/系统同时做多件事情。用于提升效率。这里要着重介绍四个概念。process(进程),进程具有自包含的独立运行环境(self-containedexcesiveenvironment),并且有着自己的内存空间(ownmemoryspace)。thread(线程),线程和进程都......
  • JavaScript笔记总结(Xmind格式):第一天
    Xmind鸟瞰图:简单文字总结:js使用方法:        1.行内样式(需要特定条件才可以使用)        2.内部样式(script尽量写在body最下面)        3.外部样式(在script标签中通过src引入外部的js文件)window对象的方法(window可以省略):        1.alert......
  • JavaScript笔记总结(Xmind格式):第二天
    Xmind鸟瞰图:简单文字总结:数据类型检测:可以使用typeof检测数据类型数据类型转换:  1.其它类型转换为Boolearn    ①数字类型转换Boolean:只有0会被转换为false,其它的非0数字都会转换为true    ②字符串类型转换为Boolean:只有空字符串会被转换为false,......
  • JavaScript笔记总结(Xmind格式):第三天
    Xmind鸟瞰图:简单文字总结:数组的创建:  1.数组的特性:    ①数组中,可以添加任意的数据类型    ②数组是一个对象,属于复杂数据类型    ③直接创建的数组可以在中间添加空值    ④构造函数创建的数据不可以添加空值,会直接报错  2.......
  • 基于java+springboot+vue实现的公司日常考勤系统(文末源码+Lw)132
     基于SpringBoot+Vue的实现的公司日常考勤系统(源码+数据库+万字Lun文+流程图+ER图+结构图+开题报告+演示视频+软件包)选题背景及意义:分析企业的考勤管理系统过程可以看到,考勤管理系统中主要要解决的是:1.考勤信息的管理;2.考勤、出勤信息的请假及申请;3.给系统设定用户登录权......
  • 基于java+springboot+vue实现的在线课程管理系统(文末源码+Lw)133
     基于SpringBoot+Vue的实现的在线课程管理系统(源码+数据库+万字Lun文+流程图+ER图+结构图+演示视频+软件包)系统功能:本在线课程管理系统有管理员,教师,学生。管理员功能有个人中心,学生管理,教师管理,在线课程管理,课件信息管理,知识要点管理,教学计划管理,考试大纲管理,科目类型管理,......
  • 基于java+springboot+vue实现的在线课程管理系统(文末源码+Lw)133
     基于SpringBoot+Vue的实现的在线课程管理系统(源码+数据库+万字Lun文+流程图+ER图+结构图+演示视频+软件包)系统功能:本在线课程管理系统有管理员,教师,学生。管理员功能有个人中心,学生管理,教师管理,在线课程管理,课件信息管理,知识要点管理,教学计划管理,考试大纲管理,科目类型管理,......
  • 深入理解 Java 类加载机制:Arthas classloader 命令解析
    引言Java虚拟机(JVM)的类加载机制是Java应用运行的基础。了解类加载器(ClassLoader)的工作原理对于解决类冲突、热部署、资源查找等问题至关重要。Arthas,作为一个强大的Java诊断工具,提供了classloader命令,帮助开发者深入理解JVM的类加载机制。本文将详细介绍classloa......
  • Java 中的线程
    创建线程的三种方式方式一:继承Thread类实现步骤:继承Thread类并重写run()方法;创建线程并启动。代码实现:publicclassMyThreadextendsThread{  @Override  publicvoidrun(){    for(inti=0;i<100;i++){      System.out.pri......