提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
自学了几种常见的排序算法,做个简单的总结
代码如下(示例):
// 将前面额冒泡排序算法,封装成一个方法 ,从小到大排序 public static void bubbleSort(int[] arr) { int temp; Boolean flag = false; //标识变量,表示是否进行过交换, //一趟下来,如果没有交换过,说明数组已经有序,则不需继续遍历 for(int i = 0;i < arr.length;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 { //交换过,要重新设置为false,为下一趟做准备 flag = false; } } }
代码如下(示例):
private static void Select(int[] arr){ for(int i = 0;i<arr.length-1;i++){ int minIndex = i;//记录最小值下标 int min = arr[i];//记录最小值 for(int j = i;j < arr.length-1;j++){ if (arr[j] < min) {//找到一个数比当前数小,就记录下来 min = arr[j]; minIndex = j; } } if(minIndex != i){//找到一个最小的值,则和最前面的数进行交换 arr[minIndex] = arr[i]; arr[i] = min; } } }
插入排序的基本思想是:把 n 个待排序的元素看成为一个有序表和一个无序表,开始时有 序表中只包含一个元素,无序表中包含有 n-1 个元素,排序过程中每次从无序表中取出第一个元素,把它的排序码依次与有序表元素的排序码进行比较,将它插入到有序表中的适当位置,使之成为新的有序表。
public static void insert(int[] arr){ int insertVal = 0; int insertIndex = 0; for(int i = 1;i < arr.length;i++){ insertVal = arr[i];//记录插入的值 insertIndex = i -1;//记录插入数的前一个数 while(insertIndex >= 0 && (insertVal < arr[insertIndex])){ //比较当前插入值和当前值,找出最小的位置插入 arr[insertIndex+1] = arr[insertIndex];//将数后移,空出插入的位置 insertIndex--;//往前面找 } if(insertIndex+1 != i){//判断指针是否有动 arr[insertIndex + 1] = insertVal;//如果有动,就将当前位置改为插入值 //为什么insertIndex 要加1 : 因为前一步出来的时候insertIndex 是多减了一下 } } }
希尔排序 是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含 的关键词越来越多,当增量减至 1 时,整个文件恰被分成一组,算法便终止
int insertVal;//记录插入值 int insertIndex;//记录当前要插入值对应的下标 for(int gap = arr.length/2;gap > 0;gap /= 2){ //将整个数据分组,分为length / 2组,并不断缩小增量 gap /= 2 for(int i = gap;i < arr.length;i++){ //每一次分组都用插入排序 //记录每一次插入排序的初始位置,从后面开始 insertVal = arr[i]; //插入值初始化 insertIndex = i; //当前要插入值的下标 while(insertIndex - gap >= 0 && (insertVal < arr[insertIndex-gap] )){ //当前要插入的前一个必须有值,否则就不会进入 //并且前一个值大于要插入的值,才能进入 arr[insertIndex] = arr[insertIndex-gap];//将前一个值移到当前位置 insertIndex-=gap;//然后位置向前移动一步 } if(insertIndex != i){//如果当前值没有动,说明当前值是已经小的了,不用插入了 arr[insertIndex] = insertVal;//否则,就将插入值,插入到当前位置 } } }
public static void QuickSort(int[] arr, int left, int right){ int l = left; int r = right; int pivot = arr[(left+right)/2];//记录中间值 int temp = 0;//临时变量,用于交换 while (l < r ){ while(arr[l] < pivot){//在左边找到一个比pivot大的数的下标 l++; } while(arr[r] > pivot){//在右边找到一个比pivot小的数的下标 r--; } if (l >= r) { break; } //交换左右两个值 temp = arr[l]; arr[l] = arr[r]; arr[r] = temp; if(arr[l] == pivot){ r--; } if(arr[r] == pivot){ l++; } if(l == r){ l++; r--; } if(left < r){ QuickSort(arr,left,r); } if(right > l){ QuickSort(arr, l, right); } } }
//分 public static void mergeSort(int[] arr, int left, int right, int[] temp) { if(left < right){ int mid = (left + right)/2; mergeSort(arr,left,mid,temp); mergeSort(arr,mid+1,right,temp); merge(arr,left,mid,right,temp); } } //治 public static void merge(int[] arr, int left, int mid, int right, int[] temp) { int i = left;//左边有序序列的初始索引 int j = mid + 1;//右边有序序列的初始索引 int t = 0;//指向temp数组的当前索引 while(i <= mid && j <= right){//继续 //如果左边的有序序列的当前元素,小于 if(arr[i] <= arr[j]){ temp[t] = arr[i]; t++; i++; } else { temp[t] = arr[j]; t++; j++; } } while(i <= mid){ temp[t++] = arr[i++]; } while(j <= right){ temp[t++] = arr[j++]; } t = 0; int tempLeft = left; while(tempLeft <= right){ arr[tempLeft++] = temp[t++]; } }
将所有待比较数值统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。 这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列
public static void radixSort(int arr[]){ //得到数组中最大的数的位数 int max = arr[0]; for (int i = 0; i < arr.length; i++) { if(arr[i] > max ){ max = arr[i]; } } //得到最大的数是多少位 int maxLength = (max + "").length(); //定义一个二维数组,表示 10 个桶, 每个桶就是一个一维数组 // 说明 // 1. 二维数组包含 10 个一维数组 // 2. 为了防止在放入数的时候,数据溢出,则每个一维数组(桶),大小定为 arr.length // 3. 名明确,基数排序是使用空间换时间的经典算法 int[][] bucket = new int[10][arr.length]; //为了记录每个桶中,实际存放了多少个数据,我们定义一个一维数组来记录各个桶的每次放入的数据个数 //比如:bucketElementCounts[0] , 记录的就是 bucket[0] 桶的放入数据个数 int[] bucketElementCounts = new int[10]; for(int i = 0,n = 1; i < maxLength;i++,n *= 10){ //n是用于的到对应数的位数 for (int j = 0; j < arr.length; j++) { int digitOfElement = arr[j]/n % 10; bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[j]; bucketElementCounts[digitOfElement]++; } //按照这个桶的顺序(一维数组的下标依次取出数据,放入原来数组) int index = 0; //遍历每一桶,并将桶中是数据,放入到原数组 for (int k = 0; k < bucketElementCounts.length; k++) { if (bucketElementCounts[k] != 0){ for (int l = 0; l < bucketElementCounts[k]; l++) { arr[index++] = bucket[k][l]; } } //第 i+1 轮处理后,需要将每个 bucketElementCounts[k] = 0 !!!! bucketElementCounts[k] = 0; } } }
跟基数排序原理差不多,这里就省略了
总结
几种排序算法,大多数都是从尚硅谷学习,大家有兴趣可以去看视频学习,在b站就可以找到相视频