1.0 十大经典排序算法 | 菜鸟教程 (runoob.com)
1 冒泡排序
一个长度为n的数组,最多需要冒泡n-1次,每冒泡1次,需要从前往后遍历n-1-i,每次比较i和i+1的值,较大值放在n+i的位置。
优化:如果在某一次冒泡时,nums[i] 和 nums[i+1]没有做交换,说明数组顺序已经排好,无须继续执行了。
/**
* 冒泡排序
* 从前往后遍历n-1次,每次比较i和i+1的值,较大值放在n+i的位置
* @param nums
*/
public static void bubbleSort(int[] nums){
int n = nums.length;
for(int j=0;j<n-1;j++){
//冒泡次数
//flag:如果某一次遍历时,没有nums[i]>nums[i+1],说明此时数组已经排序完成,直接跳出
boolean flag = true;
//在执行第j次冒泡时,数组后面的j个数已经排好序,无须再遍历
for(int i=0; i<n-1-j; i++){
if(nums[i] > nums[i+1]){
flag = false;
int temp =nums[i];
nums[i] = nums[i+1];
nums[i+1] =temp;
}
}
if(flag){
break;
}
}
}
2 选择排序
一个长度为n的数组,从第i个数字开始,依次和 i 后面的n-1个数字比较,将最小的数字放在 i 的位置
/**
* 选择排序
* @param nums
*/
public static void selectSort(int[] nums){
int n = nums.length;
for(int i=0; i<n-1; i++){
for(int j=i+1; j<n; j++){
if(nums[i] > nums[j]){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
}
}
3 快速排序
从传入的数组中选取一个基准值,然后从右往左,取出第一个小于基准值的数的位置 j ,从左往右,取出第一个大于基准值的数的位置 i ,如果此时的位置i<j,则交换i,j位置的值,然后继续递归分别对 j 两侧的数组分别排序,直至 left > right。
/**
* 快速排序
* @param nums
* @param left
* @param right
*/
public static void quickSort(int[] nums,int left, int right){
if(left >= right){return;}
int i = left;
int j = right;
//取出传入的数组中 中间的位置mid,其值作为基准值
int mid = (left+right)/2;
while(i < j){
//从右往左,取出第一个小于基准值的数的位置j
while(nums[j] > nums[mid]){
j--;
}
//从左往右,取出第一个大于基准值的数的位置i
while(nums[i] < nums[mid]){
i++;
}
//如果此时的位置i<j,则交换i,j位置的值
if(i < j){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
quickSort(nums,left,j);
quickSort(nums,j+1,right);
}
}
4 插入排序
i 从1开始,i 的左边是已排好序的,取出nums[i]放入temp,j 从 i-1 开始,从右往左遍历比较,如果比temp大,需要将 j 的值右移,最后找到比temp小的数,则把temp放进该位置
/**
* 插入排序
* @param nums
*/
public static void insertSort(int[] nums){
int n = nums.length;
for(int i=1; i<n; i++){
//i从第一个数开始,取出i位置的值
int temp = nums[i];
int j =i-1;
//j从i-1开始从右往左,如果nums[j] > temp,就把j位置的值右移一次,直到找到小于temp的值的位置
while(j>=0 && temp < nums[j]){
nums[j+1] = nums[j];
j--;
}
//找到小于temp的值的位置,就把temp放在这里
nums[j+1] =temp;
}
}