欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java 快速排序(QuickSort)原理及实现代码

程序员文章站 2024-02-17 16:39:40
快速排序(quicksort )是常用到的效率比较高的一种排序算法,在面试过程中也经常提及。下面就详细讲解一下他的原理、给出一个java版本的实现。 快速排序思想: 通...

快速排序(quicksort )是常用到的效率比较高的一种排序算法,在面试过程中也经常提及。下面就详细讲解一下他的原理、给出一个java版本的实现。

快速排序思想:

通过对数据元素集合rn 进行一趟排序划分出独立的两个部分。其中一个部分的关键字比另一部分的关键字小。然后再分别对两个部分的关键字进行一趟排序,直到独立的元素只有一个,此时整个元素集合有序。

快速排序的过程——挖坑填数法(这是一个很形象的名称),对一个元素集合r[ low ... high ] ,首先取一个数(一般是r[low] )做参照 , 以r[low]为基准重新排列所有的元素。

所有比r[low]小的放前面,所有比r[low] 大的放后面,然后以r[low]为分界,对r[low ... high] 划分为两个子集和,再做划分。直到low >=  high 。

比如:对r={37, 40, 38, 42, 461, 5, 7, 9, 12}进行一趟快速排序的过程如下(注:下面描述的内容中元素下表从 0 开始):

原始序列 37 40 38 42 461 5 7 9 12
一:high-->low 12 40 38 42 461 5 7 9 12
一:low --> high 12 40 38 42 461 5 7 9 40
二:high-->low 12 9 38 42 461 5 7 9 40
二:low --> high 12 9 38 42 461 5 7 38 40
三:high --> low 12 9 7 42 461 5 7 38 40
三:low -->high 12 9 7 42 461 5 42 38 40
四:high --> low 12 9 7 5 461 5 42 38 40
四:low --> high 12 9 7 5 461 461 42 38 40
一趟排序结果 12 9 7 5 37 461 42 38 40

开始选取基准 base = 37,初始位置下表 low = 0 , high = 8  , 从high=8,开始如果r[8] < base ,  将high位置中的内容写入到r[low]中, 将high位置空出来, low = low +1 ;

从low开始探测,由于low=1 , r[low] > base ,所以将r[low]写入到r[high] , high = high -1 ;

检测到low < high ,所以第一趟快速排序仍需继续:

此时low=1,high=7,因为 r[high] < base ,所以将 r[high] 写入到到r[low]中,low = low + 1;

从low开始探测,low = 2 , r[low] >base ,所以讲r[low]写入到r[high],high=high-1;

继续检测到 low 小于high


此时low=2,high=6,同理r[high] < base ,将r[high] 写入到r[low]中,low=low+1;

从low继续探测,low = 3 , high=6 , r[low] > base , 将r[low]写入到r[high]中,high = high-1;

继续探测到low小于high

此时low=3,high=5,同理r[high] < base,将r[high]写入到r[low]中,low = low +1;

从low继续探测,low = 4,high=5,由于r[low] > base , 将r[low]写入到r[high]中,high = high -1 ;

此时探测到low == high == 4 ;该位置即是base所在的位置,将base写入到该位置中.

然后再对子序列rs1 = {12,9,7,5} 和 rs2={461,42,38,40}做一趟快速排序,直到rsi中只有一个元素,或没有元素。

(注: 在以上表单中可以看到一趟排序中有一些重复的数据(原始数据中没有重复的数据),这是因为没有清除该位置的数据,我们在特定的时间看该内存块的数据依然是它,直到下一次将数据写入该位置位置 —— 在此该位置的数据是一个没有意义脏数据,称之为 “坑”)

快速排序的java实现:

复制代码 代码如下:

private static boolean isempty(int[] n) {
        return n == null || n.length == 0;
    }

    // ///////////////////////////////////////////////////
    /**
     * 快速排序算法思想——挖坑填数方法:
     *
     * @param n 待排序的数组
     */
    public static void quicksort(int[] n) {
        if (isempty(n))
            return;
        quicksort(n, 0, n.length - 1);
    }

    public static void quicksort(int[] n, int l, int h) {
        if (isempty(n))
            return;
        if (l < h) {
            int pivot = partion(n, l, h);
            quicksort(n, l, pivot - 1);
            quicksort(n, pivot + 1, h);
        }
    }

    private static int partion(int[] n, int start, int end) {
        int tmp = n[start];
        while (start < end) {
            while (n[end] >= tmp && start < end)
                end--;
            if (start < end) {
                n[start++] = n[end];
            }
            while (n[start] < tmp && start < end)
                start++;
            if (start < end) {
                n[end--] = n[start];
            }
        }
        n[start] = tmp;
        return start;
    }

在代码中有这样一个函数:

复制代码 代码如下:

 public static void quicksortswap(int[] n, int l, int h)

该函数可以实现,元素集合中特定的  l  到  h 位置间的数据元素进行排序。
关于快速排序就写到这里了。