排序算法

mac2024-04-01  28

常见的排序算法:冒泡排序、选择排序、快速排序、插入排序、希尔排序、归并排序、基数排序以及堆排序 先看看用方法:

package com.stuk; import java.util.*; import java.util.stream.Collectors; public class Sort { static public void main(String[] args) { // 对list的排序 List<String> list = new ArrayList<>(); list.add("abc"); list.add("aba"); list.add("abd"); List<String> result = list.stream().sorted().collect(Collectors.toList()); System.out.println(result); List<SortObj> objList = new ArrayList<SortObj>(); objList.add(new SortObj(22,"adc")); objList.add(new SortObj(11,"aba")); objList.add(new SortObj(33,"abd")); List<SortObj> result1 = objList.stream().sorted().collect(Collectors.toList()); // 按bb排序 List<SortObj> result2 = objList.stream().sorted(Comparator.comparing(SortObj::getBb)).collect(Collectors.toList()); System.out.println(result1); System.out.println(result2); // 对数组去重、排序 int[] aa = {9,7,1,3,1,2,4,2,5}; Arrays.stream(aa).sorted().forEach(t->{System.out.print(" " + t);}); // 利用数组->list->set去重排序 Set<Integer> ser = new HashSet<Integer>(); Arrays.stream(aa).forEach(t->{ser.add(t);}); // 将set转为Integer数组 Integer[] ints = ser.toArray(new Integer[]{}); int[] res = new int[ints.length]; // 转为int[] for (int i = 0; i < ints.length; i++) { res[i] = ints[i].intValue(); } Arrays.stream(res).forEach(t->{System.out.print(" " + t);}); } }

看了上面的难免疑惑,如果想sort是如何做到对int、String等做出排序的。 让你自己写一个共同的sort方法(可以处理各种类型)?有点偏题了。之后会写。 这里面肯定有各种排序。先介绍排序。 1、冒泡排序:从第一个逐一和后面的比较,默认最小值为第一个,索引为0,将最小或最大值放到第一个位置,后面依次重复操作。

package com.stuk; import java.util.*; public class Sort { static public void main(String[] args) { int[] aa = {9,7,1,3,1,2,4,2,5}; for (int i = 0; i < aa.length; i++) { // 这里一定是i+1,才能保证不会重复操作 for (int j = i + 1; j < aa.length; j++) { if (aa[i] > aa[j]) { // 升序 int tmp = aa[j]; aa[j] = aa[i]; aa[i] = tmp; } } } Arrays.stream(aa).forEach(t->{System.out.print(" " + t);}); } }

2、选择排序:每次循环记录下小/大数值的index,最后得到最大/最小的index将这个index的数值放置到首位,逐次执行,放到第二位直到最后一位。

package com.stuk; import java.util.*; public class Sort { static public void main(String[] args) { int[] aa = {9,7,1,3,1,2,4,2,5}; for (int i = 0; i < aa.length; i++) { // 记录最小index,注意它是跟着i走的,并且默认最小值为第一个 int minIndex = i; for (int j = i + 1; j < aa.length; j++) { // 要从j+1开始,避免浪费运行i=0的比较过程。 if (aa[j] < aa[minIndex]) { // 每次拿值和最小值比较,得到最小值索引 minIndex = j; } } if (minIndex != i) { int temp = aa[i]; aa[i] = aa[minIndex]; aa[minIndex] = temp; } } Arrays.stream(aa).forEach(t->{System.out.print(" " + t);}); } }

3,快速排序:是二分法的应用,速度快。简单来说,就是序列的拆分,直到不能拆分为止,每次选择一个作为基准(默认第一个),并且基准左边是比它大/小,右边是比它小/大的,再将基准归位到他在序列中排序的后的位置,再以它为准拆分为两个序列,重复上述过程(递归实现)。 过程分析: 代码实现:

package com.stuk; import java.util.*; public class Sort { static public void main(String[] args) { int[] aa = {9,7,1,3,1,2,4,2,5}; sort(aa,0,aa.length - 1); Arrays.stream(aa).forEach(t->{System.out.print(" " + t);}); } public static void sort(int[] arr, int left, int right) { // 递归结束判断 if (left > right) { return; } int i,j,temp,t; i = left; j = right; //temp就是基准位 temp = arr[left]; while (i < j) { // 先右递减后左递加(必须先右后左) while (temp <= arr[j] && i < j) { j--; } while (temp >= arr[i] && i < j) { i++; } //如果满足条件则交换 if (i < j) { t = arr[j]; arr[j] = arr[i]; arr[i] = t; } } //最后将基准为与i和j相等位置的数字交换 arr[left] = arr[i]; arr[i] = temp; //递归调用左半数组 sort(arr, left, j-1); //递归调用右半数组 sort(arr, j+1, right); } }

4、插入排序:将序列分成两个序列,一个有序序列,一个无序序列。重点是有序队列的产生,初始默认第一个为有序队列。 过程分析(比较是从后面开始的): 代码实现:

package com.stuk; import java.util.*; public class Sort { static public void main(String[] args) { int[] aa = {9,7,1,3,1,2,4,2,5}; sort(aa); Arrays.stream(aa).forEach(t->{System.out.print(" " + t);}); } public static void sort(int[] arr) { for (int i = 1; i < arr.length; i++) { int base = arr[i]; // 用j案例记录上最后的比较值,逐一往回对比找 int j = i - 1; for (; j >= 0; j--) { if (j == -1) break; // 避免数组越界 if (base < arr[j]) { // 从小到大的排序 arr[j + 1] = arr[j]; } else { break; } } // 放到最后j记录下的位置下去,由于j--,最后要j+1 arr[j + 1] = base; } } }

希尔排序:希尔排序是对插入排序的优化,减少了元素移动位置的次数。简单来说,就是以一定规律先排一定顺序,到最终顺序。 过程分析如下: 代码实现:(有那么点难了)

package com.stuk; import java.util.*; public class Sort { static public void main(String[] args) { int[] aa = {9,7,1,3,1,2,4,2,5}; sort(aa); Arrays.stream(aa).forEach(t->{System.out.print(" " + t);}); } public static void sort(int[] arrays) { //增量每次都/2 for (int step = arrays.length / 2; step > 0; step /= 2) { //从增量那组开始进行插入排序,直至完毕 for (int i = step; i < arrays.length; i++) { int j = i; int temp = arrays[j]; // j - step 就是代表与它同组隔壁的元素 while (j - step >= 0 && arrays[j - step] > temp) { arrays[j] = arrays[j - step]; j = j - step; if (j < 5) break; // 避免数组越界异常 } arrays[j] = temp; } } } }

这篇拖了很久,由于其他事要忙。以下参考别人。 归并排序: 参考:https://blog.csdn.net/qq_36442947/article/details/81612870 堆排序: https://blog.csdn.net/qq_36186690/article/details/82505569

后面几个不想写。 这里总结学习这些的最大感悟,循环不要只想着for。上面就有while要理解几种常用的情况,特别是while中嵌套if的用法。

最新回复(0)