• 冒泡排序与快速排序



     博主主页: 码农派大星.

        数据结构专栏: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. 稳定性:不稳定

  • 相关阅读:
    vscode绿色行数设置
    线程终止的 4 种方式
    OCP Java17 SE Developers 复习题06
    MQ学习之史上最全RabbitMQ(强烈建议收藏)
    TiDB 集群中能够采集的诊断数据类型
    Android 匿名共享内存的使用
    目标追踪Sort与DeepSort算法
    Qt listWidget 详细分析
    springcloud学习笔记:通过openFeign实现微服务接口远程调用
    webpack几个插件的安装使用
  • 原文地址:https://blog.csdn.net/jj666mhhh/article/details/139318786