• 快速排序Java


    我们先看图~

    换一个例子 

     

     

     

    没错
    这个流程图,
    就是快排的思想
    我们把第一个数, 成为key
    start寻找比它的数
    end寻找比它的数
    之后, start与end 进行交换
    start>=end, 我们再将 start>=end的位置下标作为下一轮的end,与start

    这是hoare法

    okk.去写代码吧~~

    哎哎哎,但是记得回来~~~ 这种方法,时间复杂度有点高!!!我们要改进一下

    1. import java.util.Arrays;
    2. public class Main {
    3. public static void main(String[] args) {
    4. int[] arr = {6,2,9,5,3,7};
    5. quickSort(arr);
    6. System.out.println(Arrays.toString(arr));
    7. }
    8. private static void quickSort(int[] arr) {
    9. quick(arr,0,arr.length-1);
    10. }
    11. // 分段
    12. private static void quick(int[] arr, int left, int right) {
    13. if(left>=right){
    14. return;
    15. }
    16. // pivot是基准
    17. int pivot = partition(arr,left,right);
    18. quick(arr,left,pivot-1);
    19. quick(arr,pivot+1,right);
    20. }
    21. // 排序
    22. private static int partition(int[] arr, int start, int end) {
    23. int i = start;
    24. int key = arr[start];
    25. while (start<end) {
    26. // key<=arr[end] 要取= 不然会死循环
    27. while (start<end && key<=arr[end]) {
    28. end--;
    29. }
    30. // key<=arr[end] 要取= 不然会死循环
    31. while (start<end && key>=arr[start]){
    32. start++;
    33. }
    34. swap(arr,start,end);
    35. }
    36. swap(arr,i,start);
    37. return start;
    38. }
    39. private static void swap(int[] arr, int start, int end) {
    40. int tmp = arr[start];
    41. arr[start] = arr[end];
    42. arr[end] = tmp;
    43. }
    44. }

     okk,我们现在说说有关时间复杂度的问题

    在理想情况下,每次都是均分待排序序列 时间复杂度 O(N*logN)
    在数组有序或者逆序时, 最慢 O(n^2)
    (并且数据太多,递归太深,还会栈溢出)
    给你康康图,这里带你推导,这个数是怎么产生的了~~~

     所以,一般情况下,快排使用场景---无序
    但是针对有序情况下我们还要进行处理,优化一下~~~

    比如--随机选取基准法--三数取中法

    介绍一下挖坑法

    我们还是先看图

    okk, 这就可以根据图, 来写代码了~~~

    1. import java.util.Arrays;
    2. public class Hole {
    3. public static void main(String[] args) {
    4. int[] arr = {4,2,9,5,3,7};
    5. quickSort(arr);
    6. System.out.println(Arrays.toString(arr));
    7. }
    8. private static void quickSort(int[] arr) {
    9. quick(arr,0,arr.length-1);
    10. }
    11. // 分段
    12. private static void quick(int[] arr, int left, int right) {
    13. if(left>=right){
    14. return;
    15. }
    16. // pivot是基准
    17. int pivot = partitionHole(arr,left,right);
    18. quick(arr,left,pivot-1);
    19. quick(arr,pivot+1,right);
    20. }
    21. // 排序
    22. private static int partitionHole(int[] arr, int start, int end) {
    23. int key = arr[start];
    24. while (start<end) {
    25. while (start<end && key<=arr[end]) {
    26. end--;
    27. }
    28. arr[start] = arr[end];
    29. while (start<end && key>=arr[start]){
    30. start++;
    31. }
    32. arr[end] = arr[start];
    33. }
    34. arr[start] = key;
    35. return start;
    36. }
    37. private static void swap(int[] arr, int start, int end) {
    38. int tmp = arr[start];
    39. arr[start] = arr[end];
    40. arr[end] = tmp;
    41. }
    42. }

     我们还有三数取中法, 前后指针法,不递归进行快排,我直接附代码啦~~!!

    1. public static void insertSort2(int[] array,int start, int end){
    2. for (int i = start; i <= end; i++) {
    3. int indix = array[i];
    4. int j = i-1;
    5. for ( ; j >= start ; j--) {
    6. if(array[j] > indix){
    7. array[j+1] = array[j];
    8. }else {
    9. break;
    10. }
    11. }
    12. array[j+1] = indix;
    13. }
    14. }
    15. private static void quick(int[] arr,int left,int right){
    16. if(left >= right){
    17. return;
    18. }
    19. if(right-left+1 <= 7){
    20. insertSort2(arr,left,right);
    21. return;
    22. }
    23. int ret = midNumber(arr,left,right);
    24. swap(arr,left,ret);
    25. int pivot = partitionHole(arr,left,right);
    26. quick(arr,left,pivot-1);
    27. quick(arr,pivot+1,right);
    28. }
    29. private static int midNumber(int[] array, int left, int right){
    30. int mid = (left+right)/2;
    31. if(left > right){
    32. if(mid > left){
    33. return left;
    34. }else if(mid < right){
    35. return right;
    36. }else {
    37. return mid;
    38. }
    39. }else {
    40. if(mid > right){
    41. return right;
    42. }else if(mid < left){
    43. return left;
    44. }else {
    45. return mid;
    46. }
    47. }
    48. }
    49. public static void quickSort(int[] arr){
    50. quick(arr,0,arr.length-1);
    51. }
    1. //指针法
    2. private static int partition(int[] arr,int start,int end){
    3. int k = arr[start];
    4. int pre = start;
    5. int cur = start+1;
    6. while(cur < end){
    7. while (arr[cur]<k && arr[++pre] != arr[cur]){
    8. swap(arr,pre,cur);
    9. }
    10. cur++;
    11. }
    12. swap(arr,pre,start);
    13. return pre;
    14. }
    1. //非递归的快速排序
    2. private static int partitionHole1(int[] arr,int start,int end){
    3. int tmp = arr[start];
    4. while (start<end){
    5. while (start<end && arr[end] >= tmp){
    6. end--;
    7. }
    8. arr[start] = arr[end];
    9. while (start<end && arr[start] <= tmp){
    10. start++;
    11. }
    12. arr[end] = arr[start];
    13. }
    14. arr[start] = tmp;
    15. return start;
    16. }
    17. private static void quick1(int[] arr,int left,int right){
    18. Stack<Integer> stack = new Stack<>();
    19. int pivot = partitionHole1(arr,left,right);
    20. if(pivot > left+1) {
    21. stack.push(left);
    22. stack.push(pivot - 1);
    23. }
    24. if(pivot < right-1) {
    25. stack.push(pivot + 1);
    26. stack.push(right);
    27. }
    28. while(!stack.empty()){
    29. right = stack.pop();
    30. left = stack.pop();
    31. pivot = partitionHole1(arr,left,right);
    32. if(pivot > left+1) {
    33. stack.push(left);
    34. stack.push(pivot - 1);
    35. }
    36. if(pivot < right-1) {
    37. stack.push(pivot + 1);
    38. stack.push(right);
    39. }
    40. }
    41. }
    42. public static void quickSort1(int[] arr){
    43. quick1(arr,0,arr.length-1);
    44. }

  • 相关阅读:
    Hadoop YARN HA 集群安装部署详细图文教程
    Java中list集合自定义排序-2022新项目
    Mysql主从复制,读写分离
    Spring Boot实现通用 Auth 认证的 4 种方式
    嵌入式UI框架 LVGL 学习笔记 02 页面管理和主题定制
    SpringBoot项目中的测试类,无法注入类,注入类为空
    7. 使用stunnel为mysql建立加密隧道
    分享一个java+python双版本源码之基于微信小程序的校园跑腿接单系统 校园快递代领小程序(源码、lw、调试)
    Spring IOC容器与 Bean 管理 第3关:Bean 标签中的 scope 属性
    十三、企业开发(4)
  • 原文地址:https://blog.csdn.net/m0_63501066/article/details/127704112