排序算法
快速排序
快速排序使用分治法来把一个串(list)分为两个子串(sub-lists)。具体算法描述如下:
从数列中挑出一个元素,称为 “基准”(pivot);
重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
动图演示
代码实现
public static void quickSort(int[] arr,int left,int right){
int l = left; //左下标
int r = right; //右下标
//pivot 中轴值
int pivot = arr[(left + right) / 2];
int temp = 0;//临时变量 作为交换时使用
//while 循环目的是让比pivot 值小的放到左边
//比 pivot大的放右边
while ( l < r){
//在pivot左边一直找 直到找到比pivot大的值 就退出
while (arr[l] < pivot){
l += 1;
}
//在pivot右边一直找 直到找到比pivot小的值 就退出
while (arr[r] > pivot){
r -= 1;
}
//如果 l>=r 说明pivot 的左右值 已经按照左边全部是 小于等于pivot值。右边全部是 大于等于pivot值
if(l >= r){
break;
}
//交换
temp = arr[l];
arr[l] = arr[r];
arr[r] = temp;
//交换完成后 发现arr[l] == pivot相等 --,前移
if(arr[l] == pivot){
r -= 1;
}
//交换完成后 发现arr[r] == pivot相等 ++,后移
if(arr[r] == pivot){
l += 1;
}
}
//如果 l == r 必须l++ , r-- ,否则就会栈溢出
if(l==r){
l += 1;
r -= 1;
}
//向左递归
if(left < r){
quickSort(arr,left,r);
}
//向右递归
if(right > l){
quickSort(arr,l,right);
}
}
插入排序:
插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
- 从第一个元素开始,该元素可以认为已经被排序;
- 取出下一个元素,在已经排序的元素序列中从后向前扫描;
- 如果该元素(已排序)大于新元素,将该元素移到下一位置;
- 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
- 将新元素插入到该位置后;
- 重复步骤2~5。
动图演示
代码实现
public static void insertSort(int[] arr){
for (int i = 1; i < arr.length ; i++) {
int insertVal = arr[i];//要比较元素的位置
int insertIndex = i - 1;//要比较的前一个元素
//insertIndex >= 0 比较的前一个元素 防止下标越界
//insertVal < arr[insertIndex] 如果要比较的元素 小于上个元素 就不用进入
while (insertIndex >= 0 && insertVal < arr[insertIndex]){
//如果要比较的元素 满足循环条件时 就将比较的元素替换为前一个元素
//然后 --再找到替换后的前一个元素 进行比较 以此类推
arr[insertIndex + 1] = arr[insertIndex];
insertIndex --;
}
//比较完成后 循环条件不满足后 把比较的值替换了
arr[insertIndex + 1] = insertVal;
}
}
选择排序:
选择排序(Selection-sort)是一种简单直观的排序算法。
它的工作原理:
- 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
- 然后,再从剩余未排序元素中继续寻找最小(大)元素。
- 然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
动图演示
代码实现
public static void selectSort(int[] arr){
for (int i = 0; i < arr.length - 1; i++) {
int minIndex = i; //假定最小数下标
int min = arr[i]; //假定最小值
for (int j = i + 1; j < arr.length; j++) {
//如果假定最小值 大于下一个比较的元素
if(min > arr[j]){
min = arr[j]; //重置min 将小于假定最小值给替换
minIndex = j; //重置minIndex 将假定最小值下标也替换
}
}
//如果最小值下标 就等于假定比较值 就说明假定的就是最小的 所以不用交换
//如果不等于 就交换一下位置
if(minIndex != i) {
arr[minIndex] = arr[i];
arr[i] = min;
}
}
}
冒泡排序:
- 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
动图演示:
代码实现
public static void bubbleSort(int[] arr){
int temp = 0;
//标识变量,表示是否交换过
//优化冒泡 如果没有进行交换过 说明已经排序完成就不需要进行多余的比较了
boolean flag = false;
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if(arr[j] > arr[j+1]){
flag = true;
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
if(!flag){
break; //如果没有交换过,说明已经排序完成
} else{
flag = false; //重置flag 进行下次判断
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)