Java语言实现快排的递归与非递归及对递归的优化

本文详细介绍了快速排序算法的原理,包括递归和非递归两种实现方式。通过代码示例,展示了如何选择基准值,以及如何优化算法以提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1 快排思想

2 递归实现代码

3 非递归实现代码


1 快排思想

每次从待排序数码中选取一个“基准值”,将该数码分成两部分,左边的一部分数值都小于该“基准值”,右边的一部分数值都大于该“基准值”,递归算法每次将左右两部分数码再次进行快排,非递归则借助栈实现,具体见以下代码:

2 递归实现代码

递归的优化可以从两方面着手:三数取中法选key和递归到小的区间时采用插入排序

public class Test {
    //最后的测试结果:1 2 2 3 4 5 5 6 7 9 22 22 23 23 33 34 44 55 56 56 56 57 66 67 77 88 90 99 345 678
    public static void main(String[] args) {
        int[] data = new int[]{6,2,4,7,9,3,1,5,22,66,44,55,33,22,77,88,99,90,2,5,56,34,56,678,345,23,23,56,57,67};
        quickSort(data,0,data.length-1);
        for (int i = 0; i < data.length; i++) {
            System.out.print(data[i]+" ");
        }
    }
    //取得基准值
    public static int partSort(int[] arr,int low,int high){
        int tmp = arr[low];
        while (low < high){
            //从后往前遍历,找到第一个比arr[low]小的值,并将其赋值在low的位置
            while (low<high && arr[high]>=tmp){
                high--;
            }
            if (low>=high){
                break;
            }else {
                arr[low] = arr[high];
            }
            //从前往后遍历,找到第一个比arr[high]大的值,将其赋值在high的位置
            while (low<high && arr[low]<=tmp){
                low++;
            }
            if (low>=high){
                break;
            }else {
                arr[high] = arr[low];
            }
        }
        //最后将基准值赋值到相应位置,并将其下标返回
        arr[low] = tmp;
        return low;
    }
    //直接插入排序
    public static void insertSort(int[] arr){
        for (int i = 1; i < arr.length; i++) {
            int tmp = arr[i];
            int j = 0;
            for (j = i-1; j >= 0 ; j--) {
                if (arr[j] > tmp){
                    arr[j+1] = arr[j];
                }else {
                    break;
                }
            }
            arr[j+1] = tmp;
        }
    }
    public static void swap(int[] arr,int a,int b){
        int tmp = arr[a];
        arr[a] = arr[b];
        arr[b] = tmp;
    }
    public static void middleThree(int[] arr,int low,int high){
        int mid = (low+high)/2;
        if (arr[mid] > arr[low]){
            swap(arr,mid,low);
        }
        if (arr[low] > arr[high]){
            swap(arr,low,high);
        }
        if (arr[mid] > arr[high]){
            swap(arr,mid,high);
        }
        //最后得:arr[mid] <= arr[low] <= arr[high]
    }
    public static void quickSort(int[] arr,int start,int end){
        //如果数组个数小于6,则进行插入排序
        if (end-start+1 <= 6){
            insertSort(arr);
            return;
        }
        //三数取中选取key
        middleThree(arr,start,end);
        //取得一次“基准值”
        int part = partSort(arr,start,end);
        //递归左边
        quickSort(arr,start,part-1);
        //递归右边
        quickSort(arr,part+1,end);
    }
}

3 非递归实现代码

import java.util.Stack;

public class Test {
    public static void main(String[] args) {
        int[] data = new int[]{6,2,4,7,9,3,1,5,22,66,44,55,33,22,77,88,99,90,2,5,56,34,56,678,345,23,23,56,57,67};
        quickSort(data);
        for (int i = 0;i < data.length;i++){
            System.out.print(data[i]+" ");
        }
    }
    public static void quickSort(int[] array) {
        //定义一个栈,用于存放low和high
        Stack<Integer> stack = new Stack<>();
        int low = 0;
        int high = array.length-1;
        //第一次将基准值取出
        int par = partion(array,low,high);
        //先进行一次判断,将基准值取出之后判断左右两边的数据个数是否大于2(只有1个数据则
        // 说明排序完成),若左右两边的数据个数大于2,则将相应的数据入栈
        //注意:将左半部分的数据入栈时,先将low入栈,再将part-1入栈,因为出栈的时候
        //先取的是high。
        if(par > low+1){
            stack.push(low);
            stack.push(par-1);
        }
        if(par < high-1) {
            stack.push(par+1);
            stack.push(high);
        }

        //该循环当栈不为空的时候进行
        while (!stack.empty()) {
            //首先取出栈中的元素,调用一次partion函数
            high = stack.pop();
            low = stack.pop();
            par = partion(array,low,high);
            //如果par左边有两个及两个数据以上,则进行入栈操作
            if(par > low+1){
                stack.push(low);
                stack.push(par-1);
            }
            //如果par右边有两个及两个数据以上,则进行入栈操作
            if(par < high-1) {
                stack.push(par+1);
                stack.push(high);
            }
        }
    }
    public static int partion(int[] array,int low,int high) {
        int tmp =  array[low];
        while (low < high) {
            while (low < high && array[high] >= tmp) {
                high--;
            }
            if(low >= high) {
                break;
            }else {
                array[low] = array[high];
            }
            while (low < high && array[low] <= tmp) {
                low++;
            }
            if(low >= high) {
                break;
            }else {
                array[high] = array[low];
            }
        }
        array[low] = tmp;
        return low;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值