Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.feingto.cloud.kit.SortAlgorithm Maven / Gradle / Ivy
package com.feingto.cloud.kit;
import lombok.extern.slf4j.Slf4j;
import java.util.Arrays;
/**
* 排序算法
*
* @author longfei
*/
@Slf4j
public class SortAlgorithm {
/**
* 插入排序:直接插入排序-稳定
*/
public static void insertSort(int[] data) {
for (int i = 1; i < data.length; i++) {
int j;
int tmp = data[i];
for (j = i; j > 0 && tmp < data[j - 1]; j--) {
data[j] = data[j - 1];
}
data[j] = tmp;
}
}
/**
* 插入排序:希尔排序-不稳定
*/
public static void shellSort(int[] data) {
int gap = data.length;
while (gap >= 1) {
gap = gap / 2;
for (int i = gap; i < data.length; i++) {
if (data[i] < data[i - gap]) {
int j;
int tmp = data[i];
data[i] = data[i - gap];
for (j = i - gap; j >= 0 && tmp < data[j]; j = j - gap) {
data[j + gap] = data[j];
}
data[j + gap] = tmp;
}
}
}
}
/**
* 交换位置
*/
private static void swap(int[] data, int i, int j) {
if (i == j) return;
data[i] = data[i] + data[j];
data[j] = data[i] - data[j];
data[i] = data[i] - data[j];
}
/**
* 选择排序:简单选择排序-不稳定
*/
public static void selectSort(int[] data) {
for (int i = 0; i < data.length; i++) {
int k = i;
for (int j = i + 1; j < data.length; j++) {
if (data[k] > data[j]) {
k = j;
}
}
swap(data, k, i);
}
}
/**
* 选择排序:堆排序-不稳定
*/
public static void heapSort(int[] data) {
for (int i = 0; i < data.length; i++) {
// 创建小顶堆:每次循环完,二叉树的根节点都是最小值,所以与此时的未排好部分最后一个值交换位置
createLittleHeap(data, data.length - 1 - i);
swap(data, 0, data.length - 1 - i);
}
}
/**
* 创建小顶堆:双亲节点小于子节点的值。从叶子节点开始,直到根节点
*/
private static void createLittleHeap(int[] data, int last) {
for (int i = last; i > 0; i--) {
int parent = (i - 1) / 2;// 当前节点的双亲节点
if (data[parent] < data[i])
swap(data, parent, i);
}
}
/**
* 交换排序:冒泡排序-稳定
*/
public static void bubbleSort(int data[]) {
for (int i = 0; i < data.length - 1; i++) {
for (int j = 0; j < data.length - 1 - i; j++) {
if (data[j] > data[j + 1]) {
swap(data, j, j + 1);
}
}
}
}
/**
* 交换排序:快速排序-不稳定
*/
public static void quickSort(int[] data) {
int pivot = data.length - 1;
int middle = getMiddle(data, 0, pivot);
quickSort(data, 0, middle - 1);// 递归对低子表递归排序
quickSort(data, middle + 1, pivot);// 递归对高子表递归排序
}
private static void quickSort(int[] data, int low, int high) {
if (low < high) {
int middle = getMiddle(data, low, high);
quickSort(data, 0, middle - 1);
quickSort(data, middle + 1, high);
}
}
private static int getMiddle(int[] data, int low, int high) {
int key = data[low];// 基准元素(空出来的位置)
while (low < high) {
while (low < high && data[high] >= key) {// 从high开始找比基准小的,与low换位置
high--;
}
data[low] = data[high];
while (low < high && data[low] <= key) {// 从low开始找比基准大,放到之前high空出来的位置上
low++;
}
data[high] = data[low];
}
data[low] = key;// low=high 是基准元素的位置(空出来的位置)
return low;
}
/**
* 归并排序-稳定
*/
public static void mergeSort(int[] data) {
mergeSort(data, 0, data.length - 1);
}
private static void mergeSort(int[] data, int left, int right) {
if (left >= right)
return;
// 找出中间索引
int center = (left + right) / 2;
// 对左边数组进行递归
mergeSort(data, left, center);
// 对右边数组进行递归
mergeSort(data, center + 1, right);
// 合并
mergeSort(data, left, center, right);
}
/**
* 将两个数组进行归并,归并前面2个数组已有序,归并后依然有序
*
* @param data 数组对象
* @param left 左数组的第一个元素的索引
* @param center 左数组的最后一个元素的索引,center+1是右数组第一个元素的索引
* @param right 右数组最后一个元素的索引
*/
private static void mergeSort(int[] data, int left, int center, int right) {
// 临时数组
int[] tmpArr = new int[data.length];
// 右数组第一个元素索引
int mid = center + 1;
// third 记录临时数组的索引
int third = left;
// 缓存左数组第一个元素的索引
int tmp = left;
while (left <= center && mid <= right) {
// 从两个数组中取出最小的放入临时数组
if (data[left] <= data[mid]) {
tmpArr[third++] = data[left++];
} else {
tmpArr[third++] = data[mid++];
}
}
// 剩余部分依次放入临时数组(实际上两个while只会执行其中一个)
while (mid <= right) {
tmpArr[third++] = data[mid++];
}
while (left <= center) {
tmpArr[third++] = data[left++];
}
// 将临时数组中的内容拷贝回原数组中(原left-right范围的内容被复制回原数组)
while (tmp <= right) {
data[tmp] = tmpArr[tmp++];
}
}
/**
* 10进制基数排序-稳定
*/
public static void radixSort(int[] data) {
int max = Arrays.stream(data).max().getAsInt();// 计算最大数的位数
radixSort(data, 10, String.valueOf(max).length());// 10进制数,有0~9一共10种情况
}
/**
* 基数排序-稳定
* 1.先循环数组中元素个位数上的数字,先根据个位数进行排序,使用二维数组进行数据存放
* 2.再进行元素十位数上的数字排序
*
* @param data 数组
* @param radix 基数 - 每位数字的范围(这里是10进制数,有0~9一共10种情况)
* @param d 代表排序元素的位数
*/
public static void radixSort(int[] data, int radix, int d) {
// 临时数组
int[] temp = new int[data.length];
// count用于记录待排序元素的信息,用来表示该位是i的数的个数
int[] count = new int[radix];
int rate = 1;
for (int i = 0; i < d; i++) {
// 重置count数组
Arrays.fill(count, 0);
// 将data中的元素完全复制到temp数组中
System.arraycopy(data, 0, temp, 0, data.length);
// 计算每个待排序数据的子关键字
for (int j = 0; j < data.length; j++) {
int subKey = (temp[j] / rate) % radix;
count[subKey]++;
}
// 统计count数组的前j位(包含j)共有多少个数
for (int j = 1; j < radix; j++) {
count[j] = count[j] + count[j - 1];
}
// 按子关键字对指定的数据进行排序
for (int m = data.length - 1; m >= 0; m--) {
int subKey = (temp[m] / rate) % radix;
data[--count[subKey]] = temp[m];// 插入到第--count[subKey]位
}
rate *= radix;// 前进一位
}
}
public static void main(String[] args) {
int data[] = {3, 5, 1, 7, 2, 4, 9, 6, 10, 8, 93754, 199, 288, 32, 63754, 183, 12, 8903};
log.debug("初始值:{}", Arrays.toString(data));
int[] array = Arrays.copyOf(data, data.length);
long start = System.currentTimeMillis();
SortAlgorithm.insertSort(array);
log.debug(">>> Execution time {}ms", System.currentTimeMillis() - start);
log.debug("插入排序:直接插入排序:{}", Arrays.toString(array));
array = Arrays.copyOf(data, data.length);
start = System.currentTimeMillis();
SortAlgorithm.shellSort(array);
log.debug(">>> Execution time {}ms", System.currentTimeMillis() - start);
log.debug("插入排序:希尔排序:{}", Arrays.toString(array));
array = Arrays.copyOf(data, data.length);
start = System.currentTimeMillis();
SortAlgorithm.selectSort(array);
log.debug(">>> Execution time {}ms", System.currentTimeMillis() - start);
log.debug("选择排序:简单选择排序:{}", Arrays.toString(array));
array = Arrays.copyOf(data, data.length);
start = System.currentTimeMillis();
SortAlgorithm.heapSort(array);
log.debug(">>> Execution time {}ms", System.currentTimeMillis() - start);
log.debug("选择排序:堆排序:{}", Arrays.toString(array));
array = Arrays.copyOf(data, data.length);
start = System.currentTimeMillis();
SortAlgorithm.bubbleSort(array);
log.debug(">>> Execution time {}ms", System.currentTimeMillis() - start);
log.debug("交换排序:冒泡排序:{}", Arrays.toString(array));
array = Arrays.copyOf(data, data.length);
start = System.currentTimeMillis();
SortAlgorithm.quickSort(array);
log.debug(">>> Execution time {}ms", System.currentTimeMillis() - start);
log.debug("交换排序:快速排序:{}", Arrays.toString(array));
array = Arrays.copyOf(data, data.length);
start = System.currentTimeMillis();
SortAlgorithm.mergeSort(array);
log.debug(">>> Execution time {}ms", System.currentTimeMillis() - start);
log.debug("归并排序:{}", Arrays.toString(array));
array = Arrays.copyOf(data, data.length);
start = System.currentTimeMillis();
SortAlgorithm.radixSort(array, 10, 5);
log.debug(">>> Execution time {}ms", System.currentTimeMillis() - start);
log.debug("基数排序:{}", Arrays.toString(array));
}
}