vlambda博客
学习文章列表

面试之选择排序——你会怎么优化她【面试踩坑优化】

面试之选择排序——你会怎么优化她【面试踩坑优化】


排序算法2-选择排序

课代表总结



选择排序比昨天写的冒泡排序更快。面试过程中,多和面试官沟通自己的优化思路,不断探讨,比干巴巴的写写写,更容易offer到手

最基本概念
选择排序(Selection sort)是一种简单直观的排序算法。 它的工作原理是: 第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。 以此类推,直到全部待排序的数据元素的个数为零。 选择排序是不稳定的排序方法。

基本思路

  • 首先假设数组中的第一个元素为待排序数组中最小的元素,即temp=arr[0],然后开始遍历数组中的其他元素,若发现第i个元素比temp小则重置temp值,即temp=arr[i]
  • 在第一趟排序时,找出数组中最小的元素,使其和arr[0]交换位置。
  • 在第二趟排序时找出第二小的元素和arr[1]交换,依次类推。
「分析」 选择排序需要进行 arr.length-1 趟的数组排序,选择排序的时间复杂度为O(n^2) 
「代码实现」
public class Select {
public static void main(String[] args) { int[] arr = new int[] { 10, 4, 2, 6, -2, 9, 0 }; selectsort1(arr); }
public static void selectsort1(int[] arr) { int temp, index; for (int i = 0; i < arr.length - 1; i++) { temp = arr[i]; index = i; for (int j = i + 1; j < arr.length; j++) { if (temp > arr[j]) { temp = arr[j]; index = j; } } if (index != i) { arr[index] = arr[i]; arr[i] = temp; } System.out.println("第" + i + "趟排序后的结果是:" + Arrays.toString(arr)); } }
输出的结果图为:
面试之选择排序——你会怎么优化她【面试踩坑优化】
选择排序

优化

  • 上面的选择排序基本思路是依次找到最小值,放到相应的位置,那么在遍历过程中既然能找到最小值,肯定也能找到最大值,并将其放在相应的位置上。
  • 因此,通过遍历,将数组中的最大值和最小值都放在相应的位置上,这样整体数组排序的趟数为(arr.length/2),减少了运行时间。
  • 下面代码每行都有思路注释,思路是最重要的!
「代码实现」
public class Selsetsort { public static void main(String[] args) { int[] arr = new int[] { 10, 4, 2, 6, -2, 9, 0 }; selectsort2(arr); System.out.println(Arrays.toString(arr)); }
public static void selectsort2(int[] arr) { int left = 0; //每次找到最小值应该放的位置 int right = (arr.length - 1); //每次找到最大值应该放的位置 int min = 0, max = 0; //记录遍历过程中找的的最小值和最大值 int temp = 0; //用来交换两个数值时使用 int mi = 0, mx = 0; //分别表示找到的最小值和最大值的下标 for (int i = 0; i < (arr.length / 2); i++) { min = arr[left]; max = arr[right]; mi = left; mx = right; if (min > max) { temp = arr[left]; arr[left] = arr[right]; arr[right] = temp; min = arr[left]; max = arr[right]; } for (int j = left + 1; j < right; j++) { if (arr[j] < min) { //找到最小值 min = arr[j]; mi = j; } if (arr[j] > max) { //找到最大值 max = arr[j]; mx = j; } } if (mi != left) { arr[mi] = arr[left]; arr[left] = min; } if (mx != right) { arr[mx] = arr[right]; arr[right] = max; } left++; right--; System.out.println("第" + i + "趟排序结果为" + Arrays.toString(arr)); } }}
运行结果图:
面试之选择排序——你会怎么优化她【面试踩坑优化】
优化选择排序
很明显的结果:优化之后,排序的趟数减少一半。

性能比较

分别随机产生80000个数据,进行从小到大排序,测试冒泡排序二次优化后的时间和选择排序的时间。
1.冒泡排序二次优化运行结果图:
面试之选择排序——你会怎么优化她【面试踩坑优化】
冒泡排序
2.选择排序未优化运行结果图:
面试之选择排序——你会怎么优化她【面试踩坑优化】
选择排序
3.选择排序优化之后结果运行图:
面试之选择排序——你会怎么优化她【面试踩坑优化】
选择排序优化
「性能结果」
冒泡排序所用时间为12秒,而选择排序优化前后都只需要1秒。因为冒泡排序和选择排序的比较次数是一样的,但是在比较过程中,冒泡排序需要交换多次,而选择排序只需要交换一次。

总结

  • 上面算法的优化思路,绝对可以让你与众不同。
  • 无论简单的算法还是更为复杂的,主要是解决问题的思路,举一反三,多思考,很多地方都可以应用的到!

PS: 笔者建了个学习交流群,禁广告、推广,大家有啥问题也可以在群里提问,有需要的小伙伴可以加一下~
加群方式 - 扫描下方👇笔者二维码,备注:直通车
原创不易,在看转发就是最大的鼓励!