本文使用Java语言实现了十大排序算法中的8种,分别是冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序以及计数排序。剩下的桶排序和基数排序有时间再补充。
package cmm;
import java.util.Arrays;
/**
* @Author:cmm
* @Date:2023/8/23 16:01
*/
public class Sort {
private static void swap(int[] array, int i, int j) {
int temp;
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
private 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]) {
swap(array, j, j + 1);
}
}
}
}
private static void selectSort(int[] array) {
for (int i = 0; i < array.length; i++) {
int minIndex = i;
for (int j = i + 1; j < array.length; j++) {
minIndex = array[minIndex] > array[j] ? j : minIndex;
}
swap(array, i, minIndex);
}
}
private static void insertSort(int[] array)
{
// for (int i = 1; i < array.length; i++) {
// int pre = i - 1;
// while (pre >= 0 && array[pre] > array[pre + 1]) {
// swap(array, pre, pre + 1);
// pre--;
// }
// }
for (int i = 1; i < array.length; i++) {
for (int pre = i - 1; pre >= 0 && array[pre] > array[pre + 1]; pre--) {
swap(array, pre, pre + 1);
}
}
}
private static void shellSort(int[] array) {
//增量序列:N/2,(N/2)/2 ... 1 该增量序列是最常用的增量序列, 但不是最优增量序列
int gap = array.length / 2;
// 对分好的每一组进行插入排序
while (gap >= 1) {
for (int i = gap; i < array.length; i++) {
for (int pre = i - gap; pre >= 0 && array[pre] > array[pre + gap]; pre -= gap ) {
swap(array, pre, pre + gap);
}
}
// 每次大循环,gap削减一半
gap = gap / 2;
}
}
private static void mergeSort(int[] array, int start, int end) {
if (start >= end) return;
int mid = (start + end) / 2; // 找中间点 start + (end - start) / 2
mergeSort(array, start, mid);
mergeSort(array, mid + 1, end);
int[] arrayTemp = new int[array.length];
for (int i = start; i <= end; i++) {
arrayTemp[i] = array[i];
}
int i = start; //表示子数组1当前元素下标
int j = mid + 1; //表示子数组2当前元素下标
//归位,每次循环会有一个元素归为到array[start, end]之间的正确位置,当前循环结束,全部元素归为完成。
for (int k = start; k <= end; k++) {
if (i > mid) {
array[k] = arrayTemp[j++];
}
else if (j > end) {
array[k] = arrayTemp[i++];
} else if (arrayTemp[i] < arrayTemp[j]){
array[k] = arrayTemp[i++];
} else {
array[k] = arrayTemp[j++];
}
}
}
private static void quickSort(int[] array, int start, int end) {
if (start > end) return;
int base = start;
int left = start;
int right = end;
while(left != right) {
while ((left != right) && (array[right] >= array[base])) {
right--;
}
while ((left != right) && (array[left] <= array[base])) {
left++;
}
if (left < right)
swap(array, left, right);
}
swap(array, base, right);
quickSort(array, start, right - 1);
quickSort(array, left + 1, end);
}
/**
* 维护堆的性质:递归
* @param array 存储堆的数组
* @param n 数组的长度
* @param i 待维护节点的下标
*/
private static void heapAdjust(int array[], int n, int i) {
int parent = i;
int lson = i * 2 + 1;
int rson = i * 2 + 2;
if (lson < n && array[parent] < array[lson]) {
largest = lson;
}
if (rson < n && array[parent] < array[rson]) {
parent = rson;
}
if (parent != i) {
swap(array, parent, i);
heapAdjust(array, n, parent);
}
}
/**
* 维护堆的性质:循环
* @param array 存储堆的数组
* @param len 数组的长度
* @param i 待维护节点的下标
*/
private static void heapAdjust2(int array[], int len, int i) {
int temp = array[i];
for (int j = 2 * i + 1; j < len; j = j * 2 + 1) {
if ((j + 1) < len && array[j] < array[j + 1]) {
j++;
}
if (temp >= array[j]) {
break;
}
else {
array[i] = array[j];
i = j;
}
}
array[i] = temp;
}
private static void heapSort(int[] array, int len) {
//建堆
for (int i = len / 2 - 1; i >= 0; i--) {
//下标为i的节点的父坐标:(i - 1) / 2 [整数除法]
heapAdjust(array, len, i);
}
//排序
for (int i = len - 1; i > 0; i--) {
swap(array, i, 0);
heapAdjust(array, i, 0);
}
}
/**
* 计数排序:通过计数而不是比较来进行排序,适用于量大范围较小的整数序列
* @param array
*/
private static void countSort(int array[], int len) {
if (len < 1) return;
// 寻找最大元素
int max = array[0];
for (int i = 1; i < len; i++) {
if (array[i] > max) {
max = array[i];
}
}
// 分配一个长度为max+1的数组存储计数,并初始化为0
int[] arrayCount = new int[max + 1];
for (int i = 0; i < arrayCount.length; i++) {
arrayCount[i] = 0;
}
// 计数
for (int i = 0; i < len; i++) {
arrayCount[array[i]]++;
}
// 统计计数的累计值
for (int i = 1; i < max + 1; i++) {
arrayCount[i] += arrayCount[i - 1];
}
// 创建一个临时数组保存结果
int[] arrayTemp = new int[len];
// 把元素放在正确的位置上
for (int i = 0; i < len; i++) {
arrayTemp[arrayCount[array[i]] - 1] = array[i];
arrayCount[array[i]]--;
}
// 将结果复制回原数组
for (int i = 0; i < len; i++) {
array[i] = arrayTemp[i];
}
}
private static void radixSort(int nums [], int n) {
return;
}
public static void main(String[] args) {
int[] array = new int[] {
1, 8, 7, 7, 5, 6, 10, 2, 15, 5, 0, 3, 0};
System.out.println(Arrays.toString(array));
// bubbleSort(array);
// selectSort(array);
// insertSort(array);
// shellSort(array);
// mergeSort(array, 0, array.length - 1);
// quickSort(array, 0, array.length - 1);
// heapSort(array, array.length);
countSort(array, array.length);
System.out.println(Arrays.toString(array));
}
}