算法笔记_015:快速排序(Java)

Posted 舞动的心

tags:

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

 目录

1 问题描述

2 解决方案

2.1 快速排序原理简介

2.2 具体编码

 

 


1 问题描述

给定一组数据,使用快速排序得到这组数据的非降序排列。

 

 


2 解决方案

2.1 快速排序原理简介

引用自百度百科:

快速排序(Quicksort)是对冒泡排序的一种改进。

快速排序由C. A. R. Hoare1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列

 

具体排序过程:

设要排序的数组A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。

 

一趟快速排序的算法是:

1)设置两个变量ij排序开始的时候:i=0j=N-1PS:即i从数组前开始向后遍历,j从数组后开始向前遍历)

2)以第一个数组元素作为关键数据,赋值给key,即key=A[0]

3)从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于key的值A[j],将A[j]A[i]互换;

4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于keyA[i],将A[i]A[j]互换;PS3)和4)步核心思想就是i向后遍历遇到大于A[0]的元素,停下来等待;j向前遍历遇到小于A[0]的元素,停下来等待;然后交换此时的A[i]A[j]的值;交换完后,i依旧自增遍历,j依旧自减遍历)

5)重复第34步,直到i=j(3,4步中,没找到符合条件的值,即3A[j]不小于key,4A[i]不大于key的时候改变ji的值,使得j=j-1i=i+1,直至找到为止。找到符合条件的值,进行交换的时候ij指针位置不变。另外,i==j这一过程一定正好是i+j-完成的时候,此时令循环结束)。

下面来看一个具体排序示例:

给定一组数据:5,3,1,9,8,2,4,7存入数组中

 

快速排序性能分析:

 

2.2 具体编码

 

package com.liuzhen.chapterFive;

public class Quicksort {
    /*
     * 该函数功能使用快速排序返回数组A的非降序序列
     * 输入数组A[0..n],其子数组为A[start..end]
     */
    public static void getQuicksort(int[] A,int start,int end){
        if(start < end){
            int s = HoarePartition(A,start,end);   //s是分裂位置,即排序结果序列的最终位置
            getQuicksort(A,start,(s-1));
            getQuicksort(A,(s+1),end);
        }
    }
    
    /*
     * 以数组第一个元素为中轴,对子数组进行划分
     * 返回分裂点在数组排序结果中的最终位置
     */
    public static int HoarePartition(int[] A,int start,int end){
        int p = A[start];
        int i = start+1;
        int j = end;
        if(i == j){
            if(A[j] >= p)   //此时分裂点右方只有一个元素,且大于分裂点处值
                return start;
        }
        while(i < j){
            while(A[i] < p){
                if(i == end)
                    break;
                i = i+1;
            }
            while(A[j] >= p){    
                if(j == (start+1)){
                    if(A[j] >= p)    //此时为分裂点右方全部是大于等于p的元素
                        return start;
                    break;
                }
                j = j-1;
            }
            swapArray(A,i,j);
        }
        swapArray(A,i,j);    //当i>=j撤换最后一次交换
        swapArray(A,j,start);
        return j;
    }
    
    /*
     * 交换数组中两个不同位置上的元素值
     */
    public static void swapArray(int[] A,int m,int n){
        int temp = A[m];
        A[m] = A[n];
        A[n] = temp;
    }
    
    //初始化一个随机数组
    public static int[] initArray(int n){
        int[] result = new int[n];
        for(int i = 0;i < n;i++)
            result[i] = (int)(Math.random()*100); //采用随机函数随机生成1~100之间的数
        return result;
            
    }
    
    public static void main(String[] args){
        int[] A = initArray(200);
        getQuicksort(A,0,(A.length-1));
        System.out.println();
        for(int i = 0;i < A.length;i++){
            if(i%10 == 0)
                System.out.println();
            System.out.print(A[i]+"\\t");
        }
    }
}

 

运行结果:

0    0    0    0    1    1    1    2    2    2    
2    2    3    3    4    4    4    7    7    7    
7    8    8    8    9    9    11    12    12    12    
13    13    14    14    15    15    16    16    17    17    
18    18    19    19    19    20    20    21    23    24    
24    24    24    25    25    25    25    25    26    26    
26    27    27    28    28    28    29    29    29    30    
30    31    31    34    34    34    35    36    37    37    
39    40    40    41    42    42    43    44    44    44    
45    45    45    45    47    48    48    48    50    50    
50    50    50    51    51    52    53    55    55    56    
56    56    57    57    58    58    58    59    60    60    
61    62    63    63    63    64    65    65    65    65    
66    66    67    68    69    69    69    70    70    72    
72    72    74    75    75    76    76    76    76    77    
77    77    78    79    79    80    81    81    81    81    
82    82    82    83    83    84    84    86    86    86    
86    87    87    87    87    87    87    87    87    88    
88    89    89    89    90    92    93    93    93    95    
95    96    96    96    97    98    98    99    99    99    

 

以上是关于算法笔记_015:快速排序(Java)的主要内容,如果未能解决你的问题,请参考以下文章

算法算法图解笔记_快速排序

算法笔记_129:计数排序(Java)

算法笔记_049:奇偶数排序(Java)

算法笔记系列:快速排序(优化)

Java学习笔记之十一Java中常用的8大排序算法详解总结

算法笔记_017:递归执行顺序的探讨(Java)