十大经典排序算法
首先排序算法可以分为内部排序算法和外部排序算法:在内存中进行的称为内部排序算法,也就是这里所说的这十种算法;相应的,当数据量很大时无法全部拷贝到内存需要使用外存,称为外部排序算法。接下来我们可用如下表来简单概括这十种算法:
表中数据说明:
- 稳定:如果A原本在B前面,而A=B,排序之后A仍然在B的前面;
- 不稳定:如果A原本在B的前面,而A=B,排序之后A可能会出现在B的后面;
- 时间复杂度: 描述一个算法执行所耗费的时间;
- 空间复杂度:描述一个算法执行所需内存的大小;
- n:数据规模;
- k:“桶”的个数;
- In-place:占用常数内存,不占用额外内存;
- Out-place:占用额外内存。
该十种排序算法可分为如下所示的两大类:
- 比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序。
- 非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此也称为线性时间非比较类排序。
冒泡排序(Bubble Sort)
算法步骤:
- 比较相邻的元素,如果第一个比第二个大,就交换它们两个;
- 对每一对相邻元素作同样的比价,从开始第一对到结尾的最后一对,这样在最后的元素就是最大的数;
- 针对所有的元素重复以上的步骤,除了数组最后已经排好序的数组;
- 重复步骤1~3,直到排序完成。
代码实现:
/**
* 冒泡排序 —— 稳定
*/
public class BubbleSort {
public static void main(String[] args) {
int[] arr = {10, 8, 5, 13, 1, 6, 9};
bubbleSort(arr);
}
private static void bubbleSort(int[] arr) {
int len = arr.length;
//外循环:内循环一次只会将一个大数冒泡到最前面,数组长度是多少就要冒泡多少次,即循环多少次
for (int i = 0; i < len - 1; i++) {
//内循坏:每次都比较相邻两个数的大小,然后交换位置,这里是将大的数往后放,会把一个最大的数往后冒泡
for (int j = 0; j < len - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
System.out.println(Arrays.toString(arr));
}
}
}
选择排序(Selection Sort)
算法步骤 :
- 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置;
- 再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾;
- 重复第2步,直到所有元素均排序完毕。
代码实现:
/**
* 选择排序 —— 不稳定
*/
public class SelectionSort {
public static void main(String[] args) {
int[] arr = {10, 8, 5, 13, 1, 6, 9};
selectionSort(arr);
}
private static void selectionSort(int[] arr) {
int len = arr.length;
for (int i = 0; i < len - 1; i++) {
//默认将当前下标作为最小值
int minVal = i;
//未排序的数组,将下标minVal与其中的每个元素都比较,选取实际最小的值,重新设置下标minVal
for (int j = i + 1; j < len; j++) {
if (arr[minVal] > arr[j]) {
minVal = j;
}
}
//如果找出来的下标与当前迭代的下标不一致,则需要交换值,从小到大排序
if (minVal != i) {
int tmp = arr[i];
arr[i] = arr[minVal];
arr[minVal] = tmp;
}
System.out.println(Arrays.toString(arr));
}
}
}
插入排序(Insertion Sort)
算法步骤:
- 首先从第一个元素开始,该元素被认为是有序的;
- 取出下一个元素,在已经排序的元素序列中从后往前进行扫描;
- 如果该已排好序的元素大于新元素,则将该元素移到下一位置;
- 重复步骤3一直往前进行扫描比较,直到找到已排序的元素小于或者等于新元素的位置;
- 将新元素插入到该位置后;
- 重复步骤2~5。
代码实现:
/**
* 插入排序 —— 稳定
*/
public class InsertionSort {
public static void main(String[] args) {
int[] arr = {10, 8, 5, 13, 1, 6, 9};
insertionSort(arr);
}
private static void insertionSort(int[] arr) {
//从第1个数开始
for (int i = 1; i < arr.length; i++) {
int val = arr[i], j = i;
//当前选择的数与前面已排序的数组的每一个数进行比较,然后交换位置,这里是从小到大排序
while (j > 0 && val < arr[j - 1]) {
arr[j] = arr[j - 1];
j--;
}
arr[j] = val;
}
System.out.println(Arrays.toString(arr));
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!