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

news/2024/5/19 23:07:32 标签: 快速排序, JAVA, 算法, 排序, 分治思想

排序>快速排序是一种最坏情况时间复杂度为 o(n^2)算法。虽然最坏情况时间复杂度很差,但是排序>快速排序通常是实际排序应用中最好的选择,因为它的平均性能非常好:它的期望时间排序复杂度是o(nlgn)

描述

与归并排序一样,排序>快速排序算法也使用了分治思想,下面是排序>快速排序的三个分治过程:

  • 分解:数组分区,此处我们取末尾元素作为划分标准,划分逻辑见下图:
    在这里插入图片描述

  • 解决:通过递归调用排序>快速排序,对左、右数组进行排序

  • 合并:因为子数组都是原址排序的,所以不需要合并。

实现

数组分区实现:以最后一个元素为样本元素,进行分区。将数组划分为左、中(样本元素存放区域)、右三组。左侧区域小于中,右侧区域大于中

    /**
     * 数组分区算法
     * 以最后一个元素为样本元素,进行分区
     * 将数组划分为左、中(样本元素存放区域)、右三组。左侧区域小于中,右侧区域大于中
     *
     * @param array 待排序数组
     * @param start 数组开始位置
     * @param end   数组结束位置
     * @return 样本元素位置
     */
    private static int partition(int[] array, int start, int end) {
        int sample = array[end];
        //默认左侧区域为空
        int leftEnd = start - 1;
        int temp;

        for (int j = start; j < end; j++) {
            //如果当前位置元素值小于样本值
            if (array[j] <= sample) {
                //将当前元素移动到左侧区域,即左侧区域空间增加1
                leftEnd++;
                temp = array[leftEnd];
                array[leftEnd] = array[j];
                array[j] = temp;
            }
        }
        //将样本元素移动到中间区域,也就是与左侧区域紧挨着
        //leftEnd + 1 就是样本元素所在位置
        //如此形成左、中、右的区间排布
        temp = array[leftEnd + 1];
        array[leftEnd + 1] = array[end];
        array[end] = temp;

        //输出分区后的数组
        System.out.println(Arrays.toString(array));
        return leftEnd + 1;
    }

排序实现:和其他的递归调用没太大区别,只需注意每次排序子数组时需要剔除掉样本元素就好。

   /**
     * 排序>快速排序
     * @param array 排序数组
     * @param start 数组起始位置
     * @param end 数组结束位置
     */
    private static void quickSort(int[] array, int start, int end) {
        if (start < end){
            //对数组进行分区,记录分区后的样本元素位置点位置
            int mid = partition(array,start,end);
            //对样本元素左侧区域进行递归排序
            quickSort(array,start,mid-1);
            //对样本元素右侧区域进行递归排序
            quickSort(array,mid+1,end);
        }
    }

此篇文章比预计晚了四天,忙里偷"闲"的生产出来,质量一般、贵在坚持!各位加油,下一篇《线性时间排序算法


http://www.niftyadmin.cn/n/1568386.html

相关文章

android adb push 和 adb install的区别

..platform\system\core\adb\commandline.c中adb push的实现 if(!strcmp(argv[0], "push")) { if(argc ! 3) return usage(); return do_sync_push(argv[1], argv[2], 0 /* no verify APK */); } 同样的文件中的函数install_app也实现了adb install实现&#xff1a; …

排序算法之计数排序(Java 版本)

计数排序是一个非基于比较的排序算法。它的优势在于在对一定范围内的整数排序时&#xff0c;它的复杂度为Ο(nk)&#xff08;其中k是整数的范围&#xff09;&#xff0c;快于任何比较排序算法。当然这是一种牺牲空间换取时间的算法。 基本思想 计数排序的基本思想是&#xff1a…

排序算法之期望为线性时间的选择算法(Java 版本)

在了解选择算法前&#xff0c;我们先熟悉一个名词顺序统计量。在集合中&#xff0c;第 i 个数序统计量指的是该集合第 i 小元素。 而选择算法处理的问题是&#xff1a;在 n 个元素组成的集合中&#xff0c;查找第 i 个顺序统计量的问题。假如i3&#xff0c;即需要查找集合中第 …

Android中 onInterceptTouchEvent, onTouchEvent 理解

onInterceptTouchEvent用于改变事件的传递方向。决定传递方向的是返回值&#xff0c;返回为false时事件会传递给子控件&#xff0c;返回值为true时事件会传递给当前控件的onTouchEvent()&#xff0c;这就是所谓的Intercept(拦截)。 [tisa ps:正确的使用方法是&#xff0c;在此…

JAVA 多线程第一部分(一)线程安全基础

并发笔记传送门&#xff1a; 1.0 并发编程-思维导图 2.0 并发编程-线程安全基础 3.0 并发编程-基础构建模块 4.0 并发编程-任务执行-Future 5.0 并发编程-多线程的性能与可伸缩性 6.0 并发编程-显式锁与synchronized 7.0 并发编程-AbstractQueuedSynchronizer 8.0 并发编程-原子…

Android中BindService方式使用的理解

最近学习了一下Android里面的Service的应用&#xff0c;在BindService部分小卡了一下&#xff0c;主要是开始没有彻底理解为什么要这么实现。 BindService和Started Service都是Service&#xff0c;有什么地方不一样呢&#xff1a; 1. Started Service中使用StartService&#…

JAVA 多线程第一部分(二)基础构建模块

并发笔记传送门&#xff1a; 1.0 并发编程-思维导图 2.0 并发编程-线程安全基础 3.0 并发编程-基础构建模块 4.0 并发编程-任务执行-Future 5.0 并发编程-多线程的性能与可伸缩性 6.0 并发编程-显式锁与synchronized 7.0 并发编程-AbstractQueuedSynchronizer 8.0 并发编程-原子…

Android之UID and PID

我们经常在一个activity中去start另一个activity&#xff0c;或者与另一个acitivity的结果进行交互&#xff08;startActivityForResult&#xff09;。但有没有想过可能会出现的permission问题呢&#xff1f;如果你遇到了permission denial的Exception&#xff0c;那么你需要读…