1、选择排序算法
选择排序(Selection Sort)是一种简单直观的排序算法,它的工作原理是每次从未排序部分选择最小(或最大)的元素,将其放到已排序部分的末尾。
2、冒泡排序算法
冒泡排序(Bubble Sort)是一种简单的排序算法,它重复地遍历要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。遍历数列的工作是重复进行的,直到没有再需要交换的元素为止。
3、插入排序算法
插入排序的基本思想是将待排序序列分为已排序区间和未排序区间,然后每次从未排序区间取出一个元素,将其插入到已排序区间的合适位置中,使得插入后仍然保持已排序区间有序。重复这个过程,直到未排序区间为空,整个序列有序为止。
4、希尔排序算法
Java希尔排序算法是一种基于插入排序的排序算法,通过将整个数组分成若干个子序列来进行排序,这些子序列是由数组元素的下标间隔一个固定的增量d所形成的。然后,对每一个子序列分别进行插入排序,使得整个序列基本有序。随着算法的进行,逐渐减小增量d的值,直到d为1时,整个数组就变为一个子序列,此时再对整个数组进行一次插入排序,即可完成排序。
5、快速排序算法
Java快速排序算法是一种高效的排序算法,它基于分治法的思想,通过递归地将数组分成较小的子数组进行排序,最终合并得到有序的数组。快速排序的基本思想是选择一个“基准”元素,然后将数组分成两个子数组,其中一个子数组的所有元素都比基准元素小,另一个子数组的所有元素都比基准元素大。接着,递归地对这两个子数组进行快速排序,直到子数组的大小为1或0,即已经有序。最后,合并这些有序的子数组,得到整个有序数组。
6、基数排序算法
基数排序(Radix Sort)是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别进行排序。又称桶排序(Bucket Sort),是一种分配式排序。它将所有待比较数值(通常为正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序,直到最高位排序完成,数列就变成一个有序序列。
二、代码实现方式
package com.test;
import java.util.Arrays;
public class SortDemo {
public static void main(String[] args) {
int[] arr = { 64, 34, 25, 12, 22, 11, 90 };
bubbleSort(arr);
System.out.println("排序后的数组: ");
for (int i : arr) {
System.out.print(i + " ");
}
}
// 1、选择排序
/*
* 选择排序的基本思想是:在未排序序列中,找到最小(或最大)的元素,存放到已排序序列的末尾。
* 随着遍历的进行,每次选出的元素都比它前面的元素大(或小)。
* 时间复杂度:O(n^2),其中n是数组的长度。空间复杂度:O(1)。
*/
public static void selectionSort(int[] arr) {
System.out.println("--选择排序--");
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;
}
}
// 将最小元素与当前元素交换
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
// 2、冒泡排序
/**
* 1、比较相邻的元素,如果第一个比第二个大,就交换他们两个
* 2、对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。这步做完了后,最后的元素就是最大的数
* 3、针对所有的元素重复以上的步骤,除了最后一个
* 4、持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较
* 5、重复步骤2到4,直到所有元素都排好序了。
* 6、冒泡排序的时间复杂度是O(n^2),其中n是数组的长度。
*/
public static void bubbleSort(int[] arr) {
System.out.println("--冒泡排序--");
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;
}
}
}
}
// 3、插入排序
/*
* 将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是末排序序列。
* 从头到尾一次扫描末排序序列,将扫描到的每一个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,
* 则将待插入元素插入到相等元素的后面)
*/
/*
* 插入排序的时间复杂度为O(n^2),其中n是待排序序列的长度。在最坏情况下,插入排序的时间复杂度为O(n^2)。在最好情况下,插入排序的时间复杂度为O
* (n),其中n是待排序序列的长度。在最坏的情况下,插入排序的空间复杂度为O(1)。
*/
public static void insertionSort(int[] arr) {
System.out.println("--插入排序--");
int n = arr.length;
for (int i = 1; i < n; i++) {
int key = arr[i];
int j = i - 1;
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j -= 1;
}
arr[j + 1] = key;
}
}
// 4、希尔排序
/*
* 希尔排序是一种插入排序的改进版本,它通过分组进行比较和交换,从而减少比较次数。
* 希尔排序的基本思想是:首先将数组分成若干个子数组,然后对每个子数组进行插入排序。接着,将子数组的大小减半,重复上述过程,直到整个数组有序。
* 希尔排序是一种高效的排序算法,适用于数据量较大的情况。
*
* 时间复杂度:O(nlogn),其中n是数组的长度。空间复杂度:O(logn)。
*/
public static void shellSort(int[] arr) {
System.out.println("--希尔排序--");
int n = arr.length;
for (int gap = n / 2; gap > 0; gap /= 2) {
for (int i = gap; i < n; i++) {
int temp = arr[i];
int j;
for (j = i - gap; j >= 0 && arr[j] > temp; j -= gap) {
arr[j + gap] = arr[j];
}
arr[j + gap] = temp;
}
}
}
// 5、快速排序
/*
* 从数列中挑出一个元素,称为 “基准”(pivot);
* 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,
* 该基准就处于数列的中间位置,这个称为分区(partition)操作;
* 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;
*/
public static void quickSort(int[] arr, int low, int high) {
if (low < high) {
int pi = partition(arr, low, high);
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
// 分区函数
private static int partition(int[] arr, int low, int high) {
int pivot = arr[high];
int i = (low - 1); // 指向小于pivot的元素的位置
for (int j = low; j <= high - 1; 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[high];
arr[high] = temp;
return (i + 1);
}
// 6、基数排序
/*
* 基数排序是一种非比较排序算法,它通过将整数按位(个、十、百等)分组来实现排序。基数排序的时间复杂度在平均情况下为O(n log r),其中n是数组的长度,r是基数的数量。
*/
public static void radixSort(int[] arr) {
int max = Arrays.stream(arr).max().getAsInt();
for (int exp = 1; max / exp > 0; exp *= 10) {
countSort(arr, exp);
}
}
private static void countSort(int[] arr, int exp) {
int n = arr.length;
int[] output = new int[n];
int[] count = new int[10];
for (int i = 0; i < n; i++) {
count[(arr[i] / exp) % 10]++;
}
for (int i = 1; i < 10; i++) {
count[i] += count[i - 1];
}
for (int i = n - 1; i >= 0; i--) {
output[count[(arr[i] / exp) % 10] - 1] = arr[i];
count[(arr[i] / exp) % 10]--;
}
System.arraycopy(output, 0, arr, 0, n);
}
}