快速排序(数据结构)

1. 前言:

这两种排序经常使用,且在算法题中经常遇见。

这里我们简单分析讨论一下。

1. 快速排序

平均时间复杂度:O(nlogn)

最坏时间复杂度: O(n^2)

1.1. 左右向中遍历:

  1. 取最右侧4为基础元素,取出后,4的位置为null。
  2. 从有空的另一侧开始遍历比较,如果左侧3的元素小于基准元素4,则不变化,反之则把左侧元素交换到右侧,左侧为null。
  3. 然后从右侧开始遍历。
  4. 反复,直到low,high指针相遇。

这种方式易于理解却不便于书写,需要反复判断是向左遍历还是向右遍历。

csharp 复制代码
public class QuickSortVariant {

    public static void main(String[] args) {
        int[] arr = {1, 3, 6, 2, 4};
        quickSort(arr, 0, arr.length - 1);
        for (int i : arr) {
            System.out.print(i + " ");
        }
    }

    public static void quickSort(int[] arr, int low, int high) {
        if (low < high) {
            int pivotIndex = partition(arr, low, high);
            quickSort(arr, low, pivotIndex - 1);
            quickSort(arr, pivotIndex + 1, high);
        }
    }

    public static int partition(int[] arr, int low, int high) {
        int pivot = arr[high]; // 选择最右侧元素作为基准
        int left = low;
        int right = high - 1;

        while (left < right) {
            // 从左侧寻找大于基准的元素
            while (arr[left] <= pivot && left < right) {
                left++;
            }
            // 从右侧寻找小于基准的元素
            while (arr[right] >= pivot && left < right) {
                right--;
            }
            // 交换左右找到的元素
            swap(arr, left, right);
        }

        // 如果最后左指针指向的元素大于基准,与基准交换
        if (arr[left] >= pivot) {
            swap(arr, left, high);
        } else {
            left++;
        }

        return left; // 返回基准元素的最终位置
    }

    public static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

1.1. 单侧遍历:

这种遍历理解麻烦点,书写却简单点。

  1. i 指针指向小于base元素的结尾。这里我指向了数组前的一个元素,这不是错误,而是一个巧妙的设计。
  2. 如果 j 指针指向的元素小于base,则 i 指针扩充一个元素,即i++,然后swap(i,j)一般情况下二者是重合的。
  3. 如果遇见大于base的指针,则j++,i 不变,等效与记录了这个大元素指针的位置,再遇到小的元素可以通过swap(i,j)交换,这时,则真正起作用。
java 复制代码
public class Solution {
    public static void main(String[] args) {
        int []arr = new int[]{1,3,6,2,4};
        sort(arr,0,4);
        System.out.println(Arrays.toString(arr));
    }

    public  static void sort(int[]arr,int low, int high){
        int baseIndex = quickSort(arr,low,high);
        quickSort(arr,low,baseIndex-1);
        quickSort(arr,baseIndex + 1,high);
    }
    public static int quickSort(int[]arr,int low, int high){
        int base = arr[high];
        int i = low - 1;
        for(int j = low; j < arr.length - 1; j++){
            if(arr[j] < base){
                i++;
                swap(arr,i,j);
            }
        }
        swap(arr,high,i + 1);
        return i + 1;



    }
    public static void swap(int[]arr,int index0, int index1){
        int tem = arr[index0];
        arr[index0] = arr[index1];
        arr[index1] = tem;
    }

}
相关推荐
IT学长编程1 小时前
计算机毕业设计 玩具租赁系统的设计与实现 Java实战项目 附源码+文档+视频讲解
java·spring boot·毕业设计·课程设计·毕业论文·计算机毕业设计选题·玩具租赁系统
莹雨潇潇1 小时前
Docker 快速入门(Ubuntu版)
java·前端·docker·容器
杨哥带你写代码1 小时前
足球青训俱乐部管理:Spring Boot技术驱动
java·spring boot·后端
小字节,大梦想1 小时前
【C++】二叉搜索树
数据结构·c++
我是哈哈hh2 小时前
专题十_穷举vs暴搜vs深搜vs回溯vs剪枝_二叉树的深度优先搜索_算法专题详细总结
服务器·数据结构·c++·算法·机器学习·深度优先·剪枝
郭二哈2 小时前
C++——模板进阶、继承
java·服务器·c++
A尘埃2 小时前
SpringBoot的数据访问
java·spring boot·后端
yang-23072 小时前
端口冲突的解决方案以及SpringBoot自动检测可用端口demo
java·spring boot·后端
沉登c2 小时前
幂等性接口实现
java·rpc
代码之光_19802 小时前
SpringBoot校园资料分享平台:设计与实现
java·spring boot·后端