排序之快速排序(java)

Posted 念奕玥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了排序之快速排序(java)相关的知识,希望对你有一定的参考价值。

快速排序是由东尼·霍尔所发展的一种排序算法。 在平均状况下,排序 n 个项目要 Ο(nlogn) 次比较。在最坏状况下则需要 Ο(n2) 次比较,但这种状况并不常见。 事实上,快速排序通常明显比其他 Ο(nlogn) 算法更快,因为它的内部循环(inner> loop)可以在大部分的架构上很有效率地被实现出来。

基本思想

分治法。快速排序又是一种分而治之思想在排序算法上的典型应用。
使用分治法(Divide and conquer)把一个串行(list)分为两个子串行(sub-lists)。
本质上来看,快速排序应该算是在冒泡排序基础上的递归分治法。
快排对效率高!它是处理大数据最快的排序算法之一,在大多数情况下都比平均时间复杂度为 O(n logn) 的排序算法表现要更好。

基本步骤:

  • 从数列中挑出一个元素,称为"基准"(pivot)。(一般是arr[0])
  • 进行分区操作:重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。
  • 递归地(recursively)把小于基准值元素的子数列和大于基准值元素的子数列排序。
    递归到最底部时,子数列的长度是零或一,也就是到了分治后到最小子数列。

递归写法如下:

public class quicksort {
    public static void main(String[] args) {
        int[] arr = {13,5,2,8,32,56,32,421,78,4};
        sort(arr,0,arr.length-1);
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+"\\t");
        }
    }
    private static void sort(int[] arr, int left,int right){
        //递归结束条件
        if(left>=right){
            return;
        }
        int low = left,high = right;
        //选出基准值
        int pivot = arr[low];
        //以pivot为标准,小数移到pivot左边,大数右边
        while (low<high){
            //pivot选在了arr[low],先从后往前找
            while (low<high && arr[high]>=pivot)
                high--;
            //遇见小数就交换
            arr[low]=arr[high];
            //从前往后找
            while ((low<high && arr[low]<=pivot))
                low++;
            //遇见大数就交换
            arr[high]=arr[low];
        }
        //pivot在low和high相交处
        arr[low]=pivot;
        //递归处理
        sort(arr,left,low-1);
        sort(arr,low+1,right);
    }
}

输出结果:

2	4	5	8	13	32	32	56	78	421	

非递归写法:

因为 递归的本质是栈 ,所以非递归实现的过程中,可以借助栈来保存中间变量。
中间变量就是通过Pritation函数划分区间之后左右两部分的首尾指针。

import java.util.LinkedList;

public class quicksort {
    public static void main(String[] args) {
        int[] arr = {13,5,2,8,32,56,32,421,78,4};
        sort1(arr);
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+"\\t");
        }
    }
    private static void sort1(int[] arr){
        LinkedList <Integer> stack = new LinkedList<Integer>();
        stack.add(0);
        stack.add(arr.length-1);
        while (!stack.isEmpty()){
            int low = stack.removeFirst();
            int high = stack.removeFirst();

            int pivotIndex = partition(arr,low,high);
            if(pivotIndex>low){
                stack.add(low);
                stack.add(pivotIndex-1);
            }
            if(pivotIndex<high && pivotIndex>=0){
                stack.add(pivotIndex+1);
                stack.add(high);
            }
        }
    }
    //分区排序
    private static int partition(int[] arr,int low,int high){
        if(low>=high) return -1;
        int left = low ,right = high;
        int pivot = arr[low];
        //小数左移,大数右移
        while (left<right){
            while (left < right && arr[right]>=pivot)
                right--;
            arr[left]=arr[right];
            while (left<right && arr[left]<=pivot)
                left++;
            arr[right]=arr[left];
        }
        //放置pivot
        arr[left]=pivot;
        //返回基准值的下标
        return left;
    }

输出结果:

2	4	5	8	13	32	32	56	78	421	

以上是关于排序之快速排序(java)的主要内容,如果未能解决你的问题,请参考以下文章

数据结构-排序之快速排序(使用Java代码实现)

排序算法之快速排序(Java)

排序算法之快速排序(Java)

Java排序算法之快速排序

快速排序之java实现

算法排序之堆排序