你真的懂快速排序了吗?

算法学习-快速排序

前言

今天做了一个笔试题目,大概意思就是让使用快速排序并打印中间过程。是不是感觉挺简单的。哈哈哈!!!

放上题目:

/**
 * 题目:选择合适的排序方法,使得能够按照下面方式输出
 * 输入:
 * 9
 * 25 84 21 47 15 27 68 35 20
 *
 * 打印输出:
 * 15 20 21 25 47 27 68 35 84
 * 15 20 21 25 47 27 68 35 84
 * 15 20 21 25 47 27 68 35 84
 * 15 20 21 25 35 27 47 68 84
 * 15 20 21 25 27 35 47 68 84
 * 15 20 21 25 27 35 47 68 84
 *
 * @author: dell
 * @date: 2020/7/31 - 14:13
 */

快速排序简介

  • 快速排序的思路是:把序列分为左右两部分,使得左边所有的数都比右边小;递归这个过程,直到不能在分。
  • 很简单是吧!!!!!
  • 但是当我做这个题的时候才发现,快排的实现方式真的好多。
  • 数据结构课程学的快排:当时学这个好长时间才学会,我太菜了。。。
    /**
     * 第一次学的快排:以第一个元素为基准,前后指针移动。当发现倒序进行交换
     * @param low
     * @param high
     * @return
     */
 	 static int partition01(int low,int high){
        int baseVal=arr[low];
        while (low<high){
            while (low<high&&baseVal<arr[high]){
                high--;
            }
            //交换
            if (low<high){
                arr[low]=arr[high];
                low++;
            }

            while (low<high&&baseVal>arr[low]){
                low++;
            }
            
            if (low<high){
                arr[high]=arr[low];
                high--;
            }
        }
        arr[low]=baseVal;
        return low;
    }

另外两种快排实现方法:

    /**
     * 题目中的快排 : 以第一个元素为基准,先左侧寻找一个倒序的元素,再右侧寻找一个倒序的元素,将这两个元素交换
     * @param left
     * @param right
     * @return
     */
    static int partition02(int left, int right) {

        int pivot = arr[left];
        int l = left, r = right;
        while (l < r) {
            while (arr[r] >= pivot && l < r) {
                r--;
            }
            while (arr[l] <= pivot && l < r) {
                l++;
            }
            if (l < r) {
                int temp = arr[l];
                arr[l] = arr[r];
                arr[r] = temp;
            }
        }
        arr[left] = arr[l];
        arr[l] = pivot;
        return l;
    }

    /**
     * 算法书上的思路 : 以最后一个为基准,两个指针{i,j}从头部开始,循环j->length发现倒序,让 j 与 i 交换
     * @param left
     * @param right
     * @return
     */
    static int partition03(int left,int right){
        int i=left;
        int temp=arr[right];
        for (int j=left;j<right;j++){
            if (arr[j]<temp){
                int tem = arr[i];
                arr[i] = arr[j];
                arr[j] = tem;
                i++;
            }
        }
        int tem = arr[i];
        arr[i] = arr[right];
        arr[right] = tem;
        return i;
    }

Ac代码


import java.util.Scanner;

/**
 * 题目:选择合适的排序方法,使得能够按照下面方式输出
 * 输入:
 * 9
 * 25 84 21 47 15 27 68 35 20
 *
 * 打印输出:
 * 15 20 21 25 47 27 68 35 84
 * 15 20 21 25 47 27 68 35 84
 * 15 20 21 25 47 27 68 35 84
 * 15 20 21 25 35 27 47 68 84
 * 15 20 21 25 27 35 47 68 84
 * 15 20 21 25 27 35 47 68 84
 *
 * @author: dell
 * @date: 2020/7/31 - 14:13
 */
public class T2 {
    static int n;

    static int arr[];

    static void quickSort(int low,int high,int ind){
        if (low<high){
            int mid;
            if (ind==1){
                mid=partition01(low,high);
            }
            else if (ind==2){
                mid=partition02(low,high);
            }
            else {
                mid=partition03(low,high);
            }
            print();
            quickSort(low,mid-1,ind);
            quickSort(mid+1,high,ind);
        }
    }

    /**
     * 第一次学的快排:以第一个元素为基准,前后指针移动。当发现倒序进行交换
     * @param low
     * @param high
     * @return
     */
    static int partition01(int low,int high){
        int baseVal=arr[low];
        while (low<high){
            while (low<high&&baseVal<arr[high]){
                high--;
            }
            //交换
            if (low<high){
                arr[low]=arr[high];
                low++;
            }

            while (low<high&&baseVal>arr[low]){
                low++;
            }

            if (low<high){
                arr[high]=arr[low];
                high--;
            }
        }
        arr[low]=baseVal;
        return low;
    }

    /**
     * 题目中的快排 : 以第一个元素为基准,先左侧寻找一个倒序的元素,再右侧寻找一个倒序的元素,将这两个元素交换
     * @param left
     * @param right
     * @return
     */
    static int partition02(int left, int right) {

        int pivot = arr[left];
        int l = left, r = right;
        while (l < r) {
            while (arr[r] >= pivot && l < r) {
                r--;
            }
            while (arr[l] <= pivot && l < r) {
                l++;
            }
            if (l < r) {
                int temp = arr[l];
                arr[l] = arr[r];
                arr[r] = temp;
            }
        }
        arr[left] = arr[l];
        arr[l] = pivot;
        return l;
    }

    /**
     * 算法书上的思路 : 以最后一个为基准,两个指针{i,j}从头部开始,循环j->length发现倒序,让 j 与 i 交换
     * @param left
     * @param right
     * @return
     */
    static int partition03(int left,int right){
        int i=left;
        int temp=arr[right];
        for (int j=left;j<right;j++){
            if (arr[j]<temp){
                int tem = arr[i];
                arr[i] = arr[j];
                arr[j] = tem;
                i++;
            }
        }
        int tem = arr[i];
        arr[i] = arr[right];
        arr[right] = tem;
        return i;
    }

    static void print(){
        for (int i=0;i<n;i++){
            if (i==0){
                System.out.print(arr[i]);
            }
            else {
                System.out.print(" "+arr[i]);
            }
        }
        System.out.println();
    }

    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        n=sc.nextInt();
        arr=new int[n];
        for (int i=0;i<n;i++){
            arr[i]=sc.nextInt();
        }
        quickSort(0,n-1,2);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值