前言
本文简单说下排序算法,比较常见的排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。
冒泡排序
冒泡排序(Bubble Sort):通过比较相邻元素的大小,将较大的元素逐渐交换到右侧,实现逐步排序。
代码语言:javascript复制 //冒泡排序
public static void bubbleSort(int[] arr) {
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;
}
}
}
}
@Test
void test() {
int[] arr = {2, 5, 3, 1, 4, 6};
mergeSort(arr);
System.out.println("排序结果:");
for (int j : arr) {
System.out.print(j " ");
}
}
输出:
代码语言:javascript复制排序结果:
1 2 3 4 5 6
该算法遍历并找到未排序部分的最小元素,并将其与当前位置的元素交换,从而逐步形成有序序列。
选择排序
选择排序(Selection Sort):每次从未排序的部分选择最小(或最大)的元素,将其放在已排序部分的末尾,逐步构建有序序列。
代码语言:javascript复制 //选择排序
public static void selectionSort(int[] arr) {
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[minIndex];
arr[minIndex] = arr[i];
arr[i] = temp;
}
}
@Test
void test() {
int[] arr = {2, 5, 3, 1, 4, 6};
selectionSort(arr);
System.out.println("排序结果:");
for (int j : arr) {
System.out.print(j " ");
}
}
输出:
代码语言:javascript复制排序结果:
1 2 3 4 5 6
该算法遍历并找到未排序部分的最小元素,并将其与当前位置的元素交换,从而逐步形成有序序列。
插入排序
插入排序(Insertion Sort):将数组分为已排序和未排序两部分,逐个将未排序的元素插入到已排序部分的正确位置。
代码语言:javascript复制 //插入排序
public static void insertionSort(int[] arr) {
int n = arr.length;
for (int i = 1; i < n; i ) {
int key = arr[i];
int j = i - 1;
// 将大于 key 的元素向右移动
while (j >= 0 && arr[j] > key) {
arr[j 1] = arr[j];
j--;
}
arr[j 1] = key;
}
}
@Test
void test() {
int[] arr = {2, 5, 3, 1, 4, 6};
insertionSort(arr);
System.out.println("排序结果:");
for (int j : arr) {
System.out.print(j " ");
}
}
输出:
代码语言:javascript复制排序结果:
1 2 3 4 5 6
该算法将数组分为已排序和未排序两部分,将未排序部分的元素逐个插入到已排序部分的正确位置。在每次插入过程中,将大于待插入元素的元素向右移动,直到找到合适的位置。
快速排序
快速排序(Quick Sort):选择一个基准元素,将数组划分为小于基准和大于基准的两个子数组,然后递归地对子数组进行排序。
代码语言:javascript复制 //快速排序
public static void quickSort(int[] arr) {
quickSort(arr, 0, arr.length - 1);
}
private static void quickSort(int[] arr, int low, int high) {
if (low < high) {
// 划分数组并获取划分点的索引
int partitionIndex = partition(arr, low, high);
// 对划分点的左侧和右侧子数组递归地进行快速排序
quickSort(arr, low, partitionIndex - 1);
quickSort(arr, partitionIndex 1, high);
}
}
private static int partition(int[] arr, int low, int high) {
// 选择最右侧的元素作为基准
int pivot = arr[high];
int i = low - 1;
for (int j = low; j < high; 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;
}
@Test
void test() {
int[] arr = {2, 5, 3, 1, 4, 6};
quickSort(arr);
System.out.println("排序结果:");
for (int j : arr) {
System.out.print(j " ");
}
}
输出:
代码语言:javascript复制排序结果:
1 2 3 4 5 6
快速排序算法通过选择一个基准元素,将数组划分为小于基准和大于基准的两个子数组,然后递归地对子数组进行排序,最终将整个数组排序。在示例中,我们选择最右侧的元素作为基准,并使用双指针的方式进行划分和交换。
归并排序
归并排序(Merge Sort):将数组递归地分成两半,对两半分别进行排序,然后将两个有序的子数组合并成一个有序数组。是一个基于分治法思想的算法
代码语言:javascript复制//归并排序
public static void mergeSort(int[] arr) {
int n = arr.length;
int[] temp = new int[n];
mergeSort(arr, temp, 0, n - 1);
}
private static void mergeSort(int[] arr, int[] temp, int low, int high) {
if (low < high) {
int mid = (low high) / 2;
mergeSort(arr, temp, low, mid);
mergeSort(arr, temp, mid 1, high);
merge(arr, temp, low, mid, high);
}
}
private static void merge(int[] arr, int[] temp, int low, int mid, int high) {
System.arraycopy(arr, low, temp, low, high - low 1);
int i = low;
int j = mid 1;
int k = low;
while (i <= mid && j <= high) {
if (temp[i] <= temp[j]) {
arr[k] = temp[i];
i ;
} else {
arr[k] = temp[j];
j ;
}
k ;
}
while (i <= mid) {
arr[k] = temp[i];
i ;
k ;
}
}
@Test
void test() {
int[] arr = {2, 5, 3, 1, 4, 6};
mergeSort(arr);
System.out.println("排序结果:");
for (int j : arr) {
System.out.print(j " ");
}
}
输出:
代码语言:javascript复制排序结果:
1 2 3 4 5 6
归并排序算法使用分治的思想,将数组不断地分割为较小的子数组,然后将这些子数组进行合并,最终得到有序的数组。此处使用了 System.arraycopy() 方法将待排序的数组复制到临时数组中,避免了多次复制的操作。
结尾
这里只简单的列出几个,后续更新文章会补上。