当前位置:   article > 正文

冒泡排序与快速排序

冒泡排序与快速排序


 博主主页: 码农派大星.

    数据结构专栏:Java数据结构

 数据库专栏:MySQL数据库

关注博主带你了解更多数据结构知识


1.冒泡排序

冒泡排序

  1. private static void swap(int[] arrary,int i,int j){
  2. int tmp = arrary[i];
  3. arrary[i] = arrary[j];
  4. arrary[j] = tmp;
  5. public static void bubbleSort(int[] arrary){
  6. for (int i = 0; i <arrary.length-1 ; i++) {
  7. for (int j = 0; j < arrary.length-1-i; j++) {
  8. if(arrary[j]> arrary[j+1]){
  9. swap(arrary,j,j+1);
  10. }
  11. }
  12. }
  13. return arrary;
  14. }

冒泡排序总结

1. 冒泡排序是一种非常容易理解的排序

2. 时间复杂度:O(N^2)

3. 空间复杂度:O(1)

4. 稳定性:稳定 

2.快速排序

快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,其基本思想为:任取待排序元素序列中的某元 素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有 元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。

1.Hoare版

  1. public static void quickSort(int[] arrary){
  2. quick(arrary,0,arrary.length-1);
  3. return arrary;
  4. }
  5. private static void swap(int[] arrary,int i,int j){
  6. int tmp = arrary[i];
  7. arrary[i] = arrary[j];
  8. arrary[j] = tmp;
  9. private static void quick(int [] arrary,int start,int end){
  10. if (start >= end) {
  11. return;
  12. }
  13. int par = partition(arrary,start,end);
  14. quick(arrary,start,par-1);
  15. quick(arrary,par+1,end);
  16. }
  17. private static int partition(int [] arrary,int left,int right){
  18. int i = left;
  19. int tmp = arrary[left];
  20. while (left < right){
  21. //right-- : 先走左边会导致最后相遇的地方比基准大的数据,
  22. // 交换完后,会把大于基准的值换到前面
  23. while (left < right && arrary[right] >= tmp){
  24. right--;
  25. }
  26. while (left < right && arrary[left] <= tmp){
  27. left++;
  28. }
  29. swap(arrary,left,right);
  30. }
  31. //此时相遇left=right;
  32. swap(arrary,left,i);
  33. return right;
  34. }

2.挖坑法 

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

3.快速排序优化

1. 三数取中法选key

  1. public static void quickSort(int[] arrary){
  2. quick(arrary,0,arrary.length-1);
  3. return arrary;
  4. }
  5. private static void quick(int [] arrary,int start,int end){
  6. if (start >= end) {
  7. return;
  8. }
  9. int index = midThreeNum(arrary,start,end);
  10. swap(arrary,index,start);
  11. int par = partitionWaken(arrary,start,end);
  12. quick(arrary,start,par-1);
  13. quick(arrary,par+1,end);
  14. }
  15. private static int partitionWaken(int [] arrary,int left,int right){
  16. int tmp = arrary[left];
  17. while (left<right){
  18. while (left < right && arrary[right] >= tmp){
  19. right--;
  20. }
  21. arrary[left] = arrary [right];
  22. while (left<right && arrary[left] <= tmp){
  23. left++;
  24. }
  25. arrary[right] = arrary[left];
  26. }
  27. arrary[left] = tmp;
  28. return left;
  29. }
  30. private static int midThreeNum(int [] arrary,int left,int right){
  31. int mid = (left+right)/2;
  32. if (arrary[left] < arrary[right]){
  33. if (arrary[mid] < arrary[left]) {
  34. return left;
  35. }else if (arrary[mid] > arrary[right]){
  36. return right;
  37. }else {
  38. return mid;
  39. }
  40. }else{
  41. if (arrary[mid] < arrary[right]){
  42. return right;
  43. }else if(arrary[mid] > arrary[left]){
  44. return left;
  45. }else {
  46. return mid;
  47. }
  48. }
  49. }

2. 递归到小的子区间时,可以考虑使用插入排序

我们在数组中数据小于等于10时改为插入排序,提高了排序的效率.

  1. public static void quickSort(int[] arrary){
  2. quick(arrary,0,arrary.length-1);
  3. return arrary;
  4. }
  5. private static void quick(int [] arrary,int start,int end){
  6. if (start >= end) {
  7. return;
  8. }
  9. if (end - start + 1 <= 10) {
  10. inserSortRange(arrary,start,end);
  11. return;
  12. }
  13. int index = midThreeNum(arrary,start,end);
  14. swap(arrary,index,start);
  15. int par = partitionWaken(arrary,start,end);
  16. quick(arrary,start,par-1);
  17. quick(arrary,par+1,end);
  18. }
  19. public static void inserSortRange(int [] array,int left,int right){
  20. for(int i = left+1; i< right;i++){
  21. int tmp = array[i];
  22. int j = i-1;
  23. for (; j >=0 ; j--) {
  24. if (array[j] > tmp) {
  25. array[j+1] = array[j];
  26. }else {
  27. //array[j+1]= tmp;
  28. break;
  29. }
  30. }
  31. array[j+1]= tmp;
  32. }
  33. }
  34. private static int partitionWaken(int [] arrary,int left,int right){
  35. int tmp = arrary[left];
  36. while (left<right){
  37. while (left < right && arrary[right] >= tmp){
  38. right--;
  39. }
  40. arrary[left] = arrary [right];
  41. while (left<right && arrary[left] <= tmp){
  42. left++;
  43. }
  44. arrary[right] = arrary[left];
  45. }
  46. arrary[left] = tmp;
  47. return left;
  48. }
  49. private static int midThreeNum(int [] arrary,int left,int right){
  50. int mid = (left+right)/2;
  51. if (arrary[left] < arrary[right]){
  52. if (arrary[mid] < arrary[left]) {
  53. return left;
  54. }else if (arrary[mid] > arrary[right]){
  55. return right;
  56. }else {
  57. return mid;
  58. }
  59. }else{
  60. if (arrary[mid] < arrary[right]){
  61. return right;
  62. }else if(arrary[mid] > arrary[left]){
  63. return left;
  64. }else {
  65. return mid;
  66. }
  67. }
  68. }

4.非递归的快速排序 

  1. //非递归快速排序
  2. public static void quickNot(int[] array){
  3. Stack<Integer> stack = new Stack<>();
  4. int left = 0;
  5. int right = array.length - 1;
  6. int par = partition(array,left,right);
  7. if (par > left+1){
  8. stack.push(left);
  9. stack.push(par-1);
  10. }
  11. if (par < right-1){
  12. stack.push(par+1);
  13. stack.push(right);
  14. }
  15. while (!stack.isEmpty()){
  16. right = stack.pop();
  17. left = stack.pop();
  18. par = partitionWaken(array,left,right);
  19. if(par > left+1){
  20. stack.push(left);
  21. stack.push(par-1);
  22. }
  23. if (par < right -1){
  24. stack.push(par+1);
  25. stack.push(right);
  26. }
  27. }
  28. return array;
  29. }
  30. private static int partition(int [] arrary,int left,int right){
  31. int i = left;
  32. int tmp = arrary[left];
  33. while (left < right){
  34. //right-- : 先走左边会导致最后相遇的地方比基准大的数据,
  35. // 交换完后,会把大于基准的值换到前面
  36. while (left < right && arrary[right] >= tmp){
  37. right--;
  38. }
  39. while (left < right && arrary[left] <= tmp){
  40. left++;
  41. }
  42. swap(arrary,left,right);
  43. }
  44. //此时相遇left=right;
  45. swap(arrary,left,i);
  46. return right;
  47. }

未优化的快速排序,再遇到数据过多时,程序会崩. 

1. 快速排序整体的综合性能和使用场景都是比较好的,所以才敢叫快速排序

2. 时间复杂度:O(N*logN)

快速排序和堆排序时间复杂度一样,但是快速排序要比堆排序快

3. 空间复杂度:O(logN)

4. 稳定性:不稳定

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

闽ICP备14008679号