Java之经典排序算法

Java之经典排序算法

本文将详细讲解 Java 中常见的经典排序算法,包括冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序和堆排序等七种算法,并给出示例代码。

冒泡排序

冒泡排序是最简单的排序算法之一,基本思想是将相邻的元素两两比较,如果前一个元素比后一个元素大,就将它们两者交换位置。重复这个过程,直到整个序列有序为止。

下面是 Java 实现代码:

public static void bubbleSort(int[] arr) {
    if (arr == null || arr.length == 0) {
        return;
    }
    int n = arr.length;
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}

选择排序

选择排序的基本思想是每次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。

下面是 Java 实现代码:

public static void selectionSort(int[] arr) {
    if (arr == null || arr.length == 0) {
        return;
    }
    int n = arr.length;
    for (int i = 0; i < n - 1; i++) {
        int minIndex = i;
        for (int j = i + 1; j < n; j++) {
            if (arr[j] < arr[minIndex]) {
                minIndex = j;
            }
        }
        if (minIndex != i) {
            int temp = arr[i];
            arr[i] = arr[minIndex];
            arr[minIndex] = temp;
        }
    }
}

插入排序

插入排序的基本思想是将待排序的元素按大小插入到已排序好的部分元素中。

下面是 Java 实现代码:

public static void insertionSort(int[] arr) {
    if (arr == null || arr.length == 0) {
        return;
    }
    int n = arr.length;
    int preIndex, current;
    for (int i = 1; i < n; i++) {
        preIndex = i - 1;
        current = arr[i];
        while (preIndex >= 0 && arr[preIndex] > current) {
            arr[preIndex + 1] = arr[preIndex];
            preIndex--;
        }
        arr[preIndex + 1] = current;
    }
}

希尔排序

希尔排序是插入排序的一种高效率改进版本。基本思想是将数组分成若干长度为 gap 的子序列,然后对每个子序列进行插入排序,最后合并成一个完整的序列。

下面是 Java 实现代码:

public static void shellSort(int[] arr) {
    if (arr == null || arr.length == 0) {
        return;
    }
    int n = arr.length;
    int gap = n / 2;
    while (gap > 0) {
        for (int i = gap; i < n; i++) {
            int j = i;
            int current = arr[i];
            while (j - gap >= 0 && current < arr[j - gap]) {
                arr[j] = arr[j - gap];
                j -= gap;
            }
            arr[j] = current;
        }
        gap /= 2;
    }
}

归并排序

归并排序是一种分治思想的排序算法,它将原始序列分为若干个子序列,分别进行排序,然后将排好序的子序列合并成一个完整的有序序列。

下面是 Java 实现代码:

public static void mergeSort(int[] arr, int left, int right) {
    if (arr == null || arr.length == 0) {
        return;
    }
    if (left < right) {
        int mid = (left + right) / 2;
        mergeSort(arr, left, mid);
        mergeSort(arr, mid + 1, right);
        merge(arr, left, mid, right);
    }
}

private static void merge(int[] arr, int left, int mid, int right) {
    int[] tmp = new int[right - left + 1];
    int i = left, j = mid + 1, k = 0;
    while (i <= mid && j <= right) {
        if (arr[i] < arr[j]) {
            tmp[k++] = arr[i++];
        } else {
            tmp[k++] = arr[j++];
        }
    }
    while (i <= mid) {
        tmp[k++] = arr[i++];
    }
    while (j <= right) {
        tmp[k++] = arr[j++];
    }
    for (int p = 0; p < tmp.length; p++) {
        arr[left + p] = tmp[p];
    }
}

快速排序

快速排序是一种分治思想的排序算法,通过一趟排序将要排序的数列分成独立的两部分,其中一部分的所有数据比另外一部分的所有数据都要小,再对这两部分数据分别进行快速排序。

下面是 Java 实现代码:

public static void quickSort(int[] arr, int left, int right) {
    if (arr == null || arr.length == 0) {
        return;
    }
    if (left < right) {
        int pivotIndex = partition(arr, left, right);
        quickSort(arr, left, pivotIndex - 1);
        quickSort(arr, pivotIndex + 1, right);
    }
}

private static int partition(int[] arr, int left, int right) {
    int pivot = arr[right];
    int i = left - 1;
    for (int j = left; j < right; j++) {
        if (arr[j] < pivot) {
            i++;
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    }
    int temp = arr[i + 1];
    arr[i + 1] = arr[right];
    arr[right] = temp;
    return i + 1;
}

堆排序

堆排序是一种树形选择排序算法,它利用了堆这种数据结构的特点进行排序,构造一个堆,将要排序的序列放在堆中,然后进行排序。

下面是 Java 实现代码:

public static void heapSort(int[] arr) {
    if (arr == null || arr.length == 0) {
        return;
    }
    int n = arr.length;
    for (int i = n / 2 - 1; i >= 0; i--) {
        adjustHeap(arr, i, n);
    }
    for (int i = n - 1; i >= 0; i--) {
        int temp = arr[0];
        arr[0] = arr[i];
        arr[i] = temp;
        adjustHeap(arr, 0, i);
    }
}

private static void adjustHeap(int[] arr, int i, int length) {
    int temp = arr[i];
    for (int j = 2 * i + 1; j < length; j = j * 2 + 1) {
        if (j + 1 < length && arr[j] < arr[j + 1]) {
            j++;
        }
        if (arr[j] > temp) {
            arr[i] = arr[j];
            i = j;
        } else {
            break;
        }
    }
    arr[i] = temp;
}

示例说明

以冒泡排序和快速排序为例,给出示例以说明排序过程。

假设要排序的数组为:

{6, 3, 8, 2, 9, 1}

冒泡排序示例

第一次排序:

[3, 6] [8, 2] [9, 1]

第二次排序:

[3, 2, 6] [8, 1, 9]

第三次排序:

[2, 3, 6, 1, 8, 9]

第四次排序:

[2, 3, 1, 6, 8, 9]

第五次排序:

[2, 1, 3, 6, 8, 9]

第六次排序:

[1, 2, 3, 6, 8, 9]

快速排序示例

以中间数 8 为枢轴进行快速排序,排序过程如下:

left=0, right=5, pivotIndex=2

[3, 6, 1, 2, 9, 8]

left=0, right=1, pivotIndex=0

[3, 6, 1, 2, 9, 8]

left=3, right=5, pivotIndex=5

[3, 6, 1, 2, 8, 9]

left=3, right=4, pivotIndex=3

[3, 2, 1, 6, 8, 9]

left=0, right=2, pivotIndex=1

[2, 3, 1, 6, 8, 9]

left=0, right=0, pivotIndex=0

[2, 3, 1, 6, 8, 9]

left=4, right=5, pivotIndex=5

[2, 3, 1, 6, 8, 9]

left=4, right=4, pivotIndex=4

[2, 3, 1, 6, 8, 9]

left=2, right=3, pivotIndex=2

[1, 3, 2, 6, 8, 9]

left=2, right=1, pivotIndex=2

[1, 3, 2, 6, 8, 9]

经过上述操作,排序完成,最终数组为:

{1, 2, 3, 6, 8, 9}

这就是冒泡排序和快速排序两种算法的基本思想、示例和 Java 实现代码。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java之经典排序算法 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • JSP使用MVC模式完成删除和修改功能实例详解

    我将详细讲解“JSP使用MVC模式完成删除和修改功能实例详解”的完整攻略。 什么是MVC? MVC是Model-View-Controller的缩写,它是一种设计模式,可用于在 Web 应用程序中实现代码和业务逻辑的分离。这样可以增强应用程序的可维护性、可拓展性和可重用性。 其中, Model(模型):存储应用程序的数据内容和业务逻辑。通常使用数据库实现。 …

    Java 2023年6月15日
    00
  • 图解Java经典算法冒泡排序的原理与实现

    下面详细讲解一下“图解Java经典算法冒泡排序的原理与实现”的完整攻略。 冒泡排序的原理 冒泡排序是一种基础的排序算法,它是通过比较相邻元素的大小来进行排序的。具体来说,它的原理是: 比较相邻的两个元素,如果前面的元素大于后面的元素,就交换它们的位置。 对每一对相邻元素做相同的操作,从开始的第一对直到结尾的最后一对。这样一轮下来,就能把最大元素排到最后。 对…

    Java 2023年5月19日
    00
  • Java数组(Array)最全汇总(中篇)

    Java数组(Array)最全汇总(中篇) 一、概述 本文讲解Java数组的相关知识点,包括定义数组、初始化、数组访问、遍历、数组长度、多维数组等。 二、定义数组 Java数组是一个存储相同类型元素的容器。数组的定义需要指定元素类型和数组大小。 使用以下语法来定义一个数组: dataType[] arrayName; //或者 dataType arrayN…

    Java 2023年5月26日
    00
  • Struts2学习笔记(3)-DMI动态调用方式

    关于“Struts2学习笔记(3)-DMI动态调用方式”的攻略,以下是详细内容: 什么是DMI动态调用方式? DMI的全称为Dynamic Method Invocation,即动态方法调用。DMI可让Struts2框架在运行时跳过了常规的Action拦截器栈,直接调用目标方法。 在DMI中,Action类中定义的方法就成了可调用的动作,Struts2框架通…

    Java 2023年5月20日
    00
  • Java面试题冲刺第二十一天–JVM

    Java面试题冲刺第二十一天–JVM 一、了解JVM 1. JVM的概念 JVM(Java Virtual Machine)即Java虚拟机,是Java语言的运行环境,负责将Java字节码文件转换为机器指令执行。 2. JVM的内部结构 JVM的内部结构分为三个部分:类加载器,运行时数据区,执行引擎。 2.1 类加载器 用来加载类文件,包括如下几种类型: …

    Java 2023年5月26日
    00
  • Java简单实现调用命令行并获取执行结果示例

    首先我们需要了解Java如何调用命令行来执行外部的命令。在Java中,可以通过ProcessBuilder或Runtime.getRuntime().exec()两种方式实现。 使用ProcessBuilder调用命令行 ProcessBuilder是一个Java API,它提供了一个类来启动外部进程并与其进行交互。下面是一个简单的Java程序,它使用Pro…

    Java 2023年5月23日
    00
  • Java中session存储Users对象实现记住密码

    当我们使用Java web开发时,常使用session来存储用户的信息以便在整个会话期间使用。如果想要实现记住密码功能,则需要将用户的用户名与密码存储在session对象中,并设置session的有效时间。下面是实现过程的完整攻略。 第一步:创建一个登录页面 首先我们需要创建一个登录页面,该页面包含一个用户名和密码的输入框以及一个“记住密码”的复选框。当用户…

    Java 2023年5月20日
    00
  • 带你快速了解Java中类和对象的关系

    一、 Java中类和对象的关系介绍 在Java中,类是代码的基本单元,是一种自定义数据类型。一个类可以包含变量、方法和构造函数。对象是类的实例,也就是类在内存中的实际存在,是通过new关键字创建的。同一个类可以创建多个不同的对象,并且每个对象都有自己的属性和行为。 二、 类和对象的关系 类和对象的关系主要表现在以下两个方面。 类是对象的模板 在Java中,我…

    Java 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部