首先,排序的分类
1.冒泡排序
动画演示
public class BubbleSort {
public static void main(String[] args) {
int[] arr = new int[]{2,10,12,1,4};
/*
n为数组的大小
冒泡排序,其中第一个for循环循环了n-1次,因此冒泡排序一共进行n-1趟的循环
每一趟循环都比较相邻的元素之间的大小,然后交换位置
如果我们发现在某趟排序中,没有发生一次交换,可以提前结束冒泡排序(这个就是优化)
比如按照从小到大排序
第一趟排序就是让最大的数排到最后 下次只需要排n-1个数
第二趟排序就是让倒数第二大的数排到后面 下次只需要排n-2个数
依次类推
*/
//优化前
// 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]){
// int temp = arr[j];
// arr[j] = arr[j + 1];
// arr[j + 1] = temp;
// }
// }
// }
//优化后
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;
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
//如果在一次排序中,一次交换都没有发生过,说明在这次排序之前就已经排好序,就直接break
if(flag == false){
break;
}else{
flag = false; //如果在这一次发生了交换,就要重置flag的值
}
}
System.out.println(Arrays.toString(arr));
}
}
2.插入排序
动画演示
public class InsertSort {
public static void main(String[] args) {
int[] arr = new int[]{2,10,12,1,4};
//使用for循环
int i , j , temp;
for (i = 1; i < arr.length; i++) {
temp = arr[i]; //temp保存将要插入的那个数字
for (j = i - 1; j >= 0; j--) {
if (temp > arr[j]) {
break;
} else {
arr[j + 1] = arr[j];
}
}
arr[j + 1] = temp; //因为最后
}
//使用while循环
// int insertVal = 0;
// int insertIndex = 0;
// for(int i = 1;i < arr.length;i++){
// //定义待插入的数
// insertVal = arr[i];
// insertIndex = i-1;//即arr[1]的前面这个数的下标
// // 给insertVal找到插入的位置
// // 说明
// // 1.insertIndex>=0保证在给insertVal找插入位置,不越界
// // 2.insertVal<arr[insertIndex]待插入的数,还没有找到插入位置
// // 3.就需要将arr[insertIndex]后移
// while(insertIndex >= 0 && insertVal<arr[insertIndex]){
// arr[insertIndex + 1]= arr[insertIndex];//arr[insertIndex]
// insertIndex--;
// }
// //当退出while循环时,说明插入的位置找到,insertIndex+1
// // 这里我们判断是否需要赋值
// if(insertIndex + 1 != i){
// arr[insertIndex + 1] = insertVal;
// }
// }
System.out.println(Arrays.toString(arr));
}
}
3.选择排序
动画演示
public class SelectSort {
public static void main(String[] args) {
int[] arr = new int[]{2,10,12,1,4};
/*
选择排序(selectsorting)也是一种简单的排序方法。
它的基本思想是:第一次从arr[0]~arr[n-1]中选取最小值,与arr[0]交换,
第二次从arr[1]~arr[n-1]中选取最小值,与arr[1]交换,
第三次从arr[2]~arr[n-1]中选取最小值,与arr[2]交换,…,
第i次从arr[i-1]~arr[n-1]中选取最小值,与arr[i-1]交换,…,
第n-1次从arr[n-2]~arr[n-1]中选取最小值,与arr[n-2]交换,
总共通过n-1次,得到一个按排序码从小到大排列的有序序列。
选择排序说明 数组长度为n
1.先择排序一共有n-1趟排序
2.每一趟排序,又是一个循环
2.1先假定当前这个数是最小数
2.2然后和后面的每一个数进行比较,如果发现比当前数更小的数,就重新确定最小数,并得到下标
2.3当遍历到数组的最后时,就得到本轮最小数和下标
2.4交换
*/
for (int i = 0; i < arr.length - 1; i++) {
int minIndex = i; //假定当前的为最小的值的下标
int min = arr[i]; //假定当前的为最小值
//j = i + 1直接从下一个开始比较
for (int j = i + 1; j < arr.length; j++) {
if (min > arr[j]) {
min = arr[j]; //重置min
minIndex = j;
}
}
//如果最小值的下标发生了改变
if (minIndex != i) {
arr[minIndex] = arr[i];
arr[i] = min;
}
}
System.out.println(Arrays.toString(arr));
}
}
4.希尔排序
动画演示
这里借用一下尚硅谷韩顺平老师的希尔排序图解
public class ShellSort {
public static void main(String[] args) {
int[] arr = new int[]{8 , 9 , 1 , 7 , 2 , 3 , 5 , 4 , 6 , 0};
int gap = arr.length / 2; //定义第一次的步长
//类比插入排序,我们分组的目的是让我们的数组呈现出”基本有序“,认真体会!!!
//最后再对整体进行一次插入排序
while (gap > 0){
//遍历各组中所有的元素(共gap组,每组中有length/gap个元素 步长为gap)
for (int i = gap ; i < arr.length ; i++) {
//第二层for循环每次都是从0开始往后遍历,这一层for循环执行完毕后,我们的j都会比原来的多1
for (int j = i - gap ; j >= 0 ; j -= gap) {
//如果当前元素大于加上步长后的那个元素,就要替换位置
if(arr[j] > arr[j + gap]) {
//使用temp作为临时变量保存值
int temp = arr[j];
arr[j] = arr[j + gap];
arr[j + gap] = temp;
}
}
}
gap /= 2;
}
System.out.println(Arrays.toString(arr));
}
}
5.快速排序
图解
我们使用中间的变量作为参照值
public class QuickSort {
public static void main(String[] args) {
int[] arr = new int[]{-9 , 78 , 0 , -567 , 70};
quickSort(arr , 0 , arr.length - 1);
System.out.println(Arrays.toString(arr));
}
//因为牵涉到递归的调用,我们就专门写一个方法来实现
//我们的left初始值就是0 right就是arr.length - 1
public static void quickSort(int[] arr , int left , int right){
int l = left;
int r = right;
//中轴值
int pivot = arr[(l + r) / 2];
//while循环的目的是让比我们pivot的值小的放在pivot左边,比他大的放在右边
while (l < r){
//在pivot的左边一直找,找到大于pivot值,找到就退出while循环
while (arr[l] < pivot){
l += 1;
}
//在pivot的右边一直找,找到小于pivot值,找到就退出while循环
while (arr[r] > pivot){
r -= 1;
}
//我们找到了比pivot的大或者小的值,就要根据l和r的值判断是否交换值
//如果l >= r就说明pivot的左右两边的值,已经按照左边全部是小于等于pivot值,右边大于pivot的值
if(l >= r){
break;
}
//交换
int temp = arr[r];
arr[r] = arr[l];
arr[l] = temp;
//如果交换完后,发现这个arr[l] == pivot r--前移
if (arr[l] == pivot){
r -= 1;
}
//如果交换完后,发现这个arr[r] == pivot l--后移
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);
}
}
}
能力有限,排序算法还有未涉及到的,如有错误,希望各位准确指出