目录
Java中常见的排序算法有以下9种:
冒泡排序(Bubble Sort)复杂度为O(n^2)
快速排序(Quick Sort) 复杂度为O(n log n)
归并排序(Merge Sort) 复杂度为O(n log n)
冒泡排序(Bubble Sort):通过相邻元素的比较和交换来逐渐将最大的元素"冒泡"到数组的末尾。时间复杂度为O(n^2)。
选择排序(Selection Sort):每次从未排序的部分选择最小(或最大)的元素放置到已排序部分的末尾。时间复杂度为O(n^2)。
插入排序(Insertion Sort):通过将元素逐个插入已排序的部分,来构建有序数组。时间复杂度为O(n^2)。
快速排序(Quick Sort):基于分治法的思想,通过选择一个分区点将数组分成左右两个子数组,递归地对子数组进行排序,最终合并得到有序数组。平均时间复杂度为O(n log n),最坏情况下为O(n^2)。
归并排序(Merge Sort):基于分治法的思想,将数组分割成两个子数组,分别对子数组进行归并排序,然后将排序后的子数组合并成一个有序数组。时间复杂度为O(n log n)。
堆排序(Heap Sort):利用堆的数据结构来实现的排序算法,通过构建最大(或最小)堆,并依次将堆顶元素放置到有序部分的末尾。时间复杂度为O(n log n)。
希尔排序(Shell Sort):将数组按一定间隔进行分组,对每个分组进行插入排序,然后逐渐缩小间隔,最终得到有序数组。时间复杂度取决于间隔序列的选择。
计数排序(Counting Sort):通过统计元素的出现次数,然后根据次数进行排序,适用于元素范围较小的情况。时间复杂度为O(n + k),其中k是元素的范围。
桶排序(Bucket Sort):将元素根据值的范围划分到不同的桶中,然后对每个桶中的元素进行排序,最后将桶中的元素依次取出得到有序数组。时间复杂度取决于桶的数量和每个桶的元素个数。
冒泡排序是一种简单的排序算法,它通过重复地交换相邻的元素,将最大的元素逐渐"冒泡"到数组的末尾。
public class BubbleSort {
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;
}
}
}
}
public static void main(String[] args) {
int[] arr = {64, 34, 25, 12, 22, 11, 90};
bubbleSort(arr);
System.out.println("排序后的数组:");
for (int num : arr) {
System.out.print(num + " ");
}
}
}
冒泡排序的基本思想是通过不断地比较相邻的元素并交换位置,将较大的元素逐渐"冒泡"到数组的末尾。它的时间复杂度是O(n^2),其中n是待排序数组的长度。冒泡排序是一种稳定的排序算法,因为相等元素的相对位置不会改变。
在上述代码中,我们使用两层循环来实现冒泡排序。外层循环控制排序的轮数,内层循环用于比较相邻元素并进行交换。每一轮内层循环都会将当前轮次最大的元素"冒泡"到数组的末尾。
冒泡排序是一种简单直观的排序算法,但由于其时间复杂度较高,在处理大规模数据时效率较低。
总结:冒泡排序是一种简单但效率较低的排序算法,通过相邻元素的比较和交换来逐渐将最大的元素"冒泡"到数组的末尾。理解和掌握这种基础的排序算法有助于加深对排序算法的理解,并为学习更复杂的排序算法打下基础。
快速排序是一种高效的排序算法,它基于分治法(Divide and Conquer)的思想,将一个大问题分解为多个小问题进行排序。
public class QuickSort {
public static void quickSort(int[] arr, int low, int high) {
if (low < high) {
int pivot = partition(arr, low, high); // 将数组分区,并返回分区点的索引
quickSort(arr, low, pivot - 1); // 递归排序左半部分
quickSort(arr, pivot + 1, high); // 递归排序右半部分
}
}
public 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; // 返回分区点的索引
}
public static void main(String[] args) {
int[] arr = {64, 34, 25, 12, 22, 11, 90};
quickSort(arr, 0, arr.length - 1);
System.out.println("排序后的数组:");
for (int num : arr) {
System.out.print(num + " ");
}
}
}
快速排序的基本思想是选择一个分区点(通常为数组的最后一个元素),将数组分成两个子数组,小于分区点的元素放在左侧,大于分区点的元素放在右侧。然后,递归地对左右两个子数组进行快速排序,直到子数组的大小为1或0时结束。
在上述代码中,我们使用递归方式实现了快速排序算法。quickSort
方法用于递归地排序数组的左半部分和右半部分,partition
方法用于进行分区操作。分区操作中,我们选择最后一个元素作为分区点,通过比较元素和分区点的大小,将元素放置到正确的位置上。
快速排序的平均时间复杂度为O(n log n),其中n是待排序数组的长度。它是一种原地排序算法,不需要额外的存储空间。快速排序是一种常用且高效的排序算法,被广泛应用于各种应用场景。
总结:快速排序是一种高效的排序算法,基于分治法的思想,通过将问题分解为多个子问题进行排序。快速排序的核心是选择分区点,并通过比较和交换操作将元素放置到正确的位置上。理解和掌握这种经典的排序算法有助于提高对排序算法的理解和应用能力。
归并排序是一种高效的排序算法,它基于分治法(Divide and Conquer)的思想,将一个大问题分解为多个小问题进行排序,然后将排序后的子数组合并成一个有序数组。
public class MergeSort {
public static void mergeSort(int[] arr) {
if (arr.length <= 1) {
return;
}
int mid = arr.length / 2;
int[] left = new int[mid];
int[] right = new int[arr.length - mid];
// 将原数组分割成左右两个子数组
System.arraycopy(arr, 0, left, 0, left.length);
System.arraycopy(arr, mid, right, 0, right.length);
// 递归对左右子数组进行归并排序
mergeSort(left);
mergeSort(right);
// 合并两个有序子数组
merge(arr, left, right);
}
public static void merge(int[] arr, int[] left, int[] right) {
int i = 0; // 左子数组的索引
int j = 0; // 右子数组的索引
int k = 0; // 合并后的数组的索引
while (i < left.length && j < right.length) {
if (left[i] <= right[j]) {
arr[k++] = left[i++];
} else {
arr[k++] = right[j++];
}
}
// 将剩余元素拷贝到合并后的数组中
while (i < left.length) {
arr[k++] = left[i++];
}
while (j < right.length) {
arr[k++] = right[j++];
}
}
public static void main(String[] args) {
int[] arr = {64, 34, 25, 12, 22, 11, 90};
mergeSort(arr);
System.out.println("排序后的数组:");
for (int num : arr) {
System.out.print(num + " ");
}
}
}
归并排序的基本思想是将一个数组分割成两个子数组,分别对这两个子数组进行归并排序,然后将排好序的子数组合并成一个有序数组。在归并排序中,关键的操作是合并两个有序子数组。
在上述代码中,我们使用递归方式实现了归并排序算法。mergeSort
方法用于递归地对数组进行归并排序,merge
方法用于合并两个有序子数组。在合并过程中,我们比较左右子数组的元素,并将较小的元素放置到合并后的数组中,直到其中一个子数组被完全合并。
归并排序的时间复杂度为O(n log n),其中n是待排序数组的长度。它是一种稳定的排序算法,并且适用于各种数据情况。归并排序的主要缺点是需要额外的存储空间来保存临时数组,但这可以通过适当的优化来减少额外空间的使用。
总结:归并排序是一种高效且稳定的排序算法,基于分治法的思想,通过将问题分解为多个子问题进行排序,然后将排序后的子数组合并成一个有序数组。理解和掌握这种经典的排序算法有助于提高对排序算法的理解和应用能力。