当前位置:   article > 正文

排序FollowUp

排序FollowUp

FollowUp

插入排序

直接插入排序

时间复杂度:
最坏情况下:0(n^2)
最好情况下:0(n)
当数据越有序 排序越快

适用于: 待排序序列 已经基本上趋于有序了!
空间复杂度:0(1)
稳定性:稳定的

  1. public static void insertSort(int[] array){
  2. for (int i = 1; i < array.length; i++) {
  3. int tmp = array[i];
  4. int j = i - 1;
  5. for (; j >= 0 ; j--) {
  6. //这里加不加等号 和稳定有关系
  7. // 但是:本身就是一个稳定的排序 可以实现为不稳定的排序
  8. // 但是 本身就是一个不稳定的排序 是不可能变成一个稳定的排序的
  9. if(array[j] > tmp){
  10. array[j + 1] = array[j];
  11. }else {
  12. break;
  13. }
  14. }
  15. array[j+1] = tmp;
  16. }
  17. }

 希尔排序(缩小增量排序)

重点是最后还是会把整体作一组来直接插入排序

  1. public static void shellSort(int[] array){
  2. int gap = array.length;
  3. while(gap > 1){
  4. shell(array,gap);
  5. gap /= 2;
  6. }
  7. }
  8. public static void shell(int[] array, int gap){
  9. for (int i = gap; i < array.length; i++) {
  10. int tmp = array[i];
  11. int j = i - gap;
  12. for (;j >= 0; j -= gap) {
  13. if(array[j] > tmp){
  14. array[j+gap] = array[j];
  15. }else {
  16. break;
  17. }
  18. }
  19. array[j+gap] = tmp;
  20. }
  21. }

 选择排序

直接选择排序

在元素集合array[i]--array[n-1]中选择关键码最大(小)的数据元素
若它不是这组元素中的最后一个(第一个)元素,则将它与这组元素中的最后一个(第一个)元素交换
在剩余的array[i]--array[n-2](array[i+1]--array[n-1])集合中,重复上述步骤,直到集合剩余1个元素

  1. public static void selectSort(int[] array){
  2. for (int i = 0; i < array.length; i++) {
  3. int mixIndex = i;
  4. for (int j = i+1; j < array.length; j++) {
  5. if(array[mixIndex] > array[j]){
  6. mixIndex = j;
  7. }
  8. }
  9. int tmp = array[i];
  10. array[i] = array[mixIndex];
  11. array[mixIndex] = tmp;
  12. }
  13. }

【直接选择排序的特性总结】
1. 直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用
2. 时间复杂度:O(N^2)
3. 空间复杂度:O(1)
4. 稳定性:不稳定

双向选择排序:

  1. public static void selectSort2(int[] array){
  2. int left = 0;
  3. int right = array.length-1;
  4. while(left < right){
  5. int minIndex = left;
  6. int maxIndex = left;
  7. for (int i = left+1; i < right; i++) {
  8. if(array[i] > array[maxIndex]){
  9. maxIndex = i;
  10. }
  11. if(array[i] < array[minIndex]){
  12. minIndex = i;
  13. }
  14. swap(array,left,minIndex);
  15. //防止最大的是在第一个的时候
  16. if(maxIndex == left){
  17. maxIndex = minIndex;
  18. }
  19. swap(array,right,maxIndex);
  20. left++;
  21. right--;
  22. }
  23. }
  24. }

堆排序

具体的思路在PriorityQueue(一)——用堆实现优先级队列

  1. public static void heapSort(int[] array){
  2. creatHeap(array);
  3. int end = array.length-1;
  4. while(end > 0){
  5. swap(array,0,end);
  6. siftDown(array,0,end);
  7. end--;
  8. }
  9. }
  10. private static void creatHeap(int[] array) {
  11. for (int parent = (array.length-1-1)/2; parent >= 0 ; parent--) {
  12. siftDown(array,parent,array.length);
  13. }
  14. }
  15. private static void siftDown(int[] array,int parent,int len) {
  16. int child = 2*parent + 1;
  17. while(child < len){
  18. if(child +1 < len && array[child] < array[child+1]){
  19. child++;
  20. }
  21. if(array[child] > array[parent]){
  22. swap(array,child,parent);
  23. parent = child;
  24. child = 2*parent + 1;
  25. }else {
  26. break;
  27. }
  28. }
  29. }
  30. public static void swap(int[] array, int i, int j){
  31. int tmp = array[i];
  32. array[i] = array[j];
  33. array[j] = tmp;
  34. }

交换排序

冒泡排序

优化:

时间复杂度:0(N^2)
如果加了优化:最好情况下 可以达到0(n)

空间复杂度:0(1)

稳定性:稳定的排序
优化:每一趟都需要判断 上一趟 有没有交换

  1. public static void bubbleSort(int[] array){
  2. for (int i = 0; i < array.length-1; i++) {
  3. boolean flg = false;
  4. for (int j = 0; j < array.length -1 - i ; j++) {
  5. if(array[j] > array[j+1]){
  6. swap(array,j,j+1);
  7. flg =true;
  8. }
  9. }
  10. //说明上一趟没有交换,也就是有序了
  11. if(!flg){
  12. break;
  13. }
  14. }
  15. }
  16. public static void swap(int[] array, int i, int j){
  17. int tmp = array[i];
  18. array[i] = array[j];
  19. array[j] = tmp;
  20. }

快速排序 

Hoare法

记录下key L和R相向出发,R找比Key小的值,L找比Key大的值,R先找找到后,L再找,两个找到交换;直到L和R相遇,相遇的位置为最后L找到的小于Key的值(让R先找的原因),此时的L就是pivot ,将Key和L交换

然后以pivot为中点,将它左右两边的循环以上操作也就是递归直到传入的L和R为相同的,那么任何一个以pivot为中点的数组都变成有序的了

pivot指的是l和r相遇的位置 

  1. public static void quickSort(int[] array){
  2. quick(array,0, array.length-1);
  3. }
  4. private static void quick(int[] array,int start,int end) {
  5. if(start >= end){
  6. return;
  7. }
  8. int pivot = partitionHoare(array,start,end);
  9. quick(array,start,pivot-1);
  10. quick(array,pivot+1,end);
  11. }
  12. private static int partitionHoare(int[] array, int left, int right) {
  13. int tmp = array[left];
  14. int i = left;
  15. while(left < right){
  16. while(left < right && array[right] >= tmp){
  17. right--;
  18. }
  19. while (left < right && array[left] <= tmp){
  20. left++;
  21. }
  22. swap(array,left,right);
  23. }
  24. swap(array,i,left);
  25. return left;
  26. }
 挖坑法

向将L的第一个位置为key,也就是坑位置,然后还是R先走找到比key小的就将R下标的值给坑位,此时R为坑位,L再走,找到比L大的值,放到坑位,L此时变为坑位,直到R和L相遇,还是保证L和R相遇的时候,是R找的比Key小的放到坑位里,然后将相遇的坑位放入Key

  1. public static void quickSort(int[] array){
  2. quick(array,0, array.length-1);
  3. }
  4. private static void quick(int[] array,int start,int end) {
  5. if(start >= end){
  6. return;
  7. }
  8. int pivot = partitionHole(array,start,end);
  9. quick(array,start,pivot-1);
  10. quick(array,pivot+1,end);
  11. }
  12. private static int partitionHole(int[] array, int left, int right) {
  13. int tmp = array[left];
  14. int t = left;
  15. while(left < right){
  16. while(left < right && array[right] >= tmp){
  17. right--;
  18. }
  19. array[left] = array[right];
  20. while (left < right && array[left] <= tmp){
  21. left++;
  22. }
  23. array[right] = array[left];
  24. }
  25. array[left] = tmp;
  26. return left;
  27. }

 

前后指针法

 

 

 记录当前电脑的时间

long startTime =System.currentTimeMillis();

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/501208
推荐阅读
相关标签
  

闽ICP备14008679号