栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

快速排序(递归+非递归)-java

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

快速排序(递归+非递归)-java

一、原理
1、从待排序区间中选择一个值作为基准值。(通常选择最左侧元素或者最右侧元素)。
2、遍历整个待排序的区间,把比基准值小的元素放在基准值左侧,比基准值大的元素放在右侧。最后整个区间就会划分为三个部分:小于基准值的元素、基准值、大于基准值的元素。
3、再针对左侧整理好的区间和右侧整理好的区间继续进行下一步的操作,重复以上过程即可。

(肯定看了这个文字的解释还是一脸懵,那就用一个例子来看一下整个的排序过程)

二、图解:

需要排序的区间:{6,1,2,7,9,3,4,5,10,8}
基准值:右侧元素-8
蓝色箭头:从左往右,找比基准值大的数字
绿色箭头:从右往左,找比基准值小的数字

第一回合:

先从左往右,找比基准值大的数字:

再从右往左,找比基准值小的数字:

交换两个数字:

再向右找比基准值大的数字:

这时,我们就会发现,两个箭头重合了,此时交换重合位置的数字和基准值。

这个时候我们就会发现,基准值8左侧的元素都比8大,右侧的都小。这样就达到了我们的目的。但是此时排序还没有结束。

我们将8左侧的元素分成一个区间{6,1,2,7,5,3,4},右侧的元素分为另一个区间{8,9}。分别将这两个区间又按照上面的方法进行排序。

第二回合:
2.1:划分{6,1,2,7,5,3,4},此时基准值我设为4

先从左向后找比基准值大的数字,在从右向左找比基准值小的数字,最后交换位置。

再继续找,这个时候两个箭头在7的位置相遇了。

交换相遇位置的元素和基准值:

这个时候又会分出两个区间{3,1,2} 和 {5,6,7},再继续进行划分。(这里我就不具体的排序了)

2.2划分{8,9},基准值为9

先从左向右找比基准值大的数字,在从右向左找比基准值小的数字。

交换重合位置元素和基准值:

这个区间就排列有序了。
此时第二回合完了之后我们的这一组数字就变成了:

一直按照这样的方法把{3,1,2}和{5,6,7}进行排序之后进行合并,就会得到一组有序的数字。

这里需要注意的是:如果取最左侧为基准值,就必须先从右向左找,再从左向右找。如果取最右侧为基准值,就必须先从左向后找,再从右向左找。

三、递归实现快速排序:

public static void quickSort(int[] array) {
        quickSortHelper(array,0,array.length-1);//辅助方法
    }

    private static void quickSortHelper(int[] array, int left, int right) {
        if(left >= right) {
            //说明这个区间中有0个或者1个元素
            return;
        }

        int index = partition(array,left,right);//重合位置的下标
        quickSortHelper(array,left,index - 1);//递归实现左区间
        quickSortHelper(array,index + 1,right);//递归实现右区间
    }

    private static int partition(int[] array, int left, int right) {
        int i = left;
        int j = right;
        int base = array[j];
        while (i < j){
            //循环从左向后找到比基准值大的元素
            while (i < j && array[i] <= base) {
                i++;
            }
            
            //代码走到这里,i有可能和j重合,也有可能是找到了比基准值大的元素
            //下面,循环从由向左找比基准值小的元素
            while (i < j && array[j] >= base) {
                j--;
            }
            
            //交换i位置的元素和j位置的元素
            swap(array,i,j);
        }
        //代码跳出循环之后,说明i和j重合了,就需要交换重合位置的元素和基准值。
        swap(array,i,right);
        return i;
    }
    private static void swap(int[] array, int i, int j) {
        int tmp = array[j];
        array[j] = array[i];
        array[i] = tmp;
    }

四、非递归实现快速排序
需要借助栈来模拟递归的一个过程。

public static void quickSortByLoop(int[] array) {
        Stack stack = new Stack<>();
        stack.push(array.length - 1);
        stack.push(0);

        while (!stack.isEmpty()) {
            int left = stack.pop();
            int right = stack.pop();

            if(left >= right) {
                continue;
            }

            int index = partition(array,left,right);
            stack.push(right);
            stack.push(index + 1);

            stack.push(index-1);
            stack.push(left);
        }
    }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/445048.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号