快速排序

基本思想:


快速排序是我们之前学习的冒泡排序的升级,他们都属于交换类排序,都是采用不断的比较和移动来实现排序的。快速排序是一种非常高效的排序算法,它的实现,增大了记录的比较和移动的距离,将关键字较大的记录从前面直接移动到后面,关键字较小的记录从后面直接移动到前面,从而减少了总的比较次数和移动次数。同时采用“分而治之”的思想,把大的拆分为小的,小的拆分为更小的,其原理如下:对于给定的一组记录,选择一个基准元素,通常选择第一个元素或者最后一个元素,通过一趟扫描,将待排序列分成两部分,一部分比基准元素小,一部分大于等于基准元素,此时基准元素在其排好序后的正确位置,然后再用同样的方法递归地排序划分的两部分,直到序列中的所有记录均有序为止。

Java实现1如下:

public class NiukeTest
{
    @Test
    public void Test()
    {
        int[] arr = { 49, 38, 65, 97, 23, 22, 76, 1, 5, 8, 2, 0, -1, 22 };
        System.out.println("排序前: ");
        for (int i = 0; i < arr.length; i++) {
            System.out.printf(arr[i] + " ");
        }
        System.out.println();
        quickSort(arr, 0, arr.length - 1);
        System.out.println("排序后: ");
        for (int i = 0; i < arr.length; i++) {
            System.out.printf(arr[i] + " ");
        }
    }

    private static void quickSort(int[] arr, int low, int high)
    {
        if(low < high){
            //寻找基准数据的正确索引
            int index = getIndex(arr, low, high);

            //进行递归对index之前和之后
            quickSort(arr, low, index - 1);
            quickSort(arr, index + 1, high);
        }
    }

    //寻找基准数据的正确索引
    private static int getIndex(int[] arr, int low, int high){

        //基准数据
        int tmp = arr[low];
        while (low < high){

            //当队尾元素小于等于tmp时,向前挪动low
            while (low < high && arr[high] >= tmp){
                high--;
            }
            //如果队尾元素小于tmp了,需要将其赋值给low
            arr[low] = arr[high];

            //当队首元素小于等于tmp时,向前挪动low
            while (low < high && arr[low] <= tmp){
                low++;
            }
            arr[high] = arr[low];
        }

        //跳出循环时low和high相等,此时的low或high就是tmp的正确索引位置
        arr[low] = tmp;
        return low; //返回tmp的正确位置
    }
}

Java实现2如下:

package sort;

import java.util.Arrays;

public class QuickSort 
{
        private static int partition(int[] arr, int low, int high) 
        {
                //指定左指针i和右指针j
                int i = low;
                int j= high;
                
                //将第一个数作为基准值。挖坑
                int x = arr[low];
                
                //使用循环实现分区操作
                while(i<j)
                {//5  8
                        //1.从右向左移动j,找到第一个小于基准值的值 arr[j]
                        while(arr[j]>=x && i<j)
                        {
                                j--;
                        }
                        //2.将右侧找到小于基准数的值加入到左边的(坑)位置, 左指针想中间移动一个位置i++
                        if(i<j)
                        {
                                arr[i] = arr[j];
                                i++;
                        }
                        //3.从左向右移动i,找到第一个大于等于基准值的值 arr[i]
                        while(arr[i] < x && i < j)
                        { 
                                i++;
                        }
                        //4.将左侧找到的打印等于基准值的值加入到右边的坑中,右指针向中间移动一个位置 j--
                        if(i<j)
                        {
                                arr[j] = arr[i];
                                j--;
                        }
                }
                
                //使用基准值填坑,这就是基准值的最终位置
                arr[i] = x;//arr[j] = y;
                //返回基准值的位置索引
                return i; //return j;
        }
        private static void quickSort(int[] arr, int low, int high) 
        {//???递归何时结束
                if(low < high)
                {
                        //分区操作,将一个数组分成两个分区,返回分区界限索引
                        int index = partition(arr,low,high);
                        //对左分区进行快排
                        quickSort(arr,low,index-1);
                        //对右分区进行快排
                        quickSort(arr,index+1,high);
                }
        
        }

        public static void quickSort(int[] arr) 
        {
                int low = 0;
                int high = arr.length-1;
                quickSort(arr,low,high);
        }
        
        public static void main(String[] args) 
        {
                //给出无序数组
                int arr[] = {72,6,57,88,60,42,83,73,48,85};

        //输出无序数组
        System.out.println(Arrays.toString(arr));
        //快速排序
        quickSort(arr);
        //partition(arr,0,arr.length-1);
        //输出有序数组
        System.out.println(Arrays.toString(arr));
        }

        
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值