1、冒泡排序
冒泡排序(Bubble Sort)是一种简单的排序算法,它重复地遍历待排序的元素列表,比较相邻的元素并交换它们的位置,直到整个列表排序完成。冒泡排序的基本思想是通过不断交换相邻元素,将最大(或最小)的元素逐渐 “冒泡” 到列表的一端。
冒泡排序的基本步骤:
- 从列表的第一个元素开始,比较它与下一个元素的大小。
- 如果当前元素大于下一个元素,则交换它们的位置,使较大的元素 “冒泡” 到列表的末尾。
- 继续比较和交换相邻元素,直到达到列表的末尾。
- 重复上述步骤,直到整个列表排序完成。
每次比较两个相邻的元素,并且按照升序或者降序
的规则进行位置的替换,需要使用到双层循环遍历,每遍历一圈只会对对一个数值进行排序,总共需要遍历n-1次;
稳定性:稳定,不会对数值相同的两个元素交换位置;
时间复杂度:O(n2);
空间复杂度:1
使用情况:适合数据量较小的情况;
冒泡排序(Bubble Sort)作为一种简单的排序算法,相比其他高级排序算法,具有一些特定的优势和应用场景:
- 实现简单: 冒泡排序的实现非常简单直观,易于理解和实现。它只涉及相邻元素的比较和交换操作,不需要复杂的数据结构或算法。
- 代码量小: 冒泡排序的代码相对较短,逻辑清晰。这使得它在教学和简单排序需求的场景中非常受欢迎。
- 适用于小规模数据: 冒泡排序对于小规模的数据集来说是一个有效的排序算法。在这种情况下,性能差异与其他高级排序算法相对较小。
- 原地排序: 冒泡排序可以在原始数组上进行排序,不需要额外的内存空间。这对于内存受限的环境或对空间复杂性要求较高的场景非常有用。
代码实现:
public static void main(String[] args) {
// 冒泡排序方式
int[] a = {2, 5, 9, 7, 8, 1, 4};
for (int i = 0; i < a.length - 1; i++) {
for (int j = 0; j < a.length - 1 - i; j++) {
if (a[j] > a[j + 1]) {
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
}
2、快速排序
快速排序(Quick Sort)是一种常用且高效的排序算法,它采用分治的思想。快速排序的基本思想是选择一个基准元素,将列表中的元素分割为两部分,使得左边部分的所有元素小于基准元素,右边部分的所有元素大于基准元素,然后对这两部分分别进行递归排序。
快速排序的基本步骤:
- 选择一个基准元素。通常可以选择列表的第一个元素、最后一个元素或随机选择。
- 将列表分割为两部分,使得左边部分的所有元素小于基准元素,右边部分的所有元素大于基准元素。这个过程称为分区(partitioning)。
- 对分割后的两部分递归地应用快速排序算法。即分别对左边部分和右边部分进行快速排序。
- 合并排序后的左右两部分,得到最终排序结果。
快速排序的平均时间复杂度是 O(n log n),其中 n 是待排序列表的长度。尽管快速排序在大多数情况下表现良好,但在最坏情况下,时间复杂度为 O(n^2)。快速排序是一种常用的排序算法,被广泛应用于各种编程环境和场景中。
稳定性:不稳定,数值相同的两个元素可能交换位置;
时间复杂度:O(nlogn),如果
基数
刚好为最大或者最小值则为O(n2);空间复杂度:O(nlogn),如果
基数
刚好为最大或者最小值则为O(n);使用情况:适合数据量较小的情况;
快速排序(Quick Sort)作为一种高效的排序算法,在很多方面具有优势:
- 高性能: 快速排序是一种基于比较的排序算法,其平均时间复杂度为 O(n log n),其中 n 是待排序列表的长度。在实际应用中,快速排序通常表现出很高的性能,特别是对于大规模数据集。
- 原地排序: 快速排序可以在原始数组上进行排序,不需要额外的内存空间。它通过交换元素来排序,避免了频繁的数据移动,节省了内存的使用。
- 适应性强: 快速排序对于各种类型的数据集都表现良好,包括随机数据、部分有序数据或包含大量重复元素的数据。通过选择合适的基准元素和应用优化技巧,快速排序可以适应不同的数据分布,提供高效的排序性能。
- 递归结构: 快速排序使用递归的思想进行分治,将大问题分解为小问题进行解决。这种结构使得算法的实现简洁清晰,并且易于理解和调试。
- 稳定性: 快速排序是一种不稳定的排序算法,即相同元素的顺序可能会在排序过程中改变。然而,通过合理的实现和优化,可以处理稳定性的需求。
代码实现:
public static void main(String[] args) {
int[] b = {4, 5, 9, 7, 8, 1, 4, 3, 7, 9, 10};
quickSort(b, 0, b.length - 1);
}
private static void quickSort(int[] b, int left, int right) {
if (left > right) {
return;
}
int i = left;
int j = right;
//temp就是基准位
int temp = b[left];
while (i < j) {
//先看右边,依次往左递减
while (temp <= b[j] && i < j) {
j--;
}
//再看左边,依次往右递增
while (temp >= b[i] && i < j) {
i++;
}
//如果满足条件则交换
if (i < j) {
int t = b[j];
b[j] = b[i];
b[i] = t;
}
}
// 将基数与i=j位置的数据交换,一次生成新的基数,并且将再进行对两头的数据进行递归处理
b[left] = b[i];
b[i] = temp;
//递归调用左半数组
quickSort(b, left, j - 1);
//递归调用右半数组
quickSort(b, j + 1, right);
}