黑马程序员:快速排序及随机化算法

------- android培训java培训、期待与您交流! ----------
快速排序(Quicksort)是对冒泡排序的一种改进。由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

快速排序的基本思想:首先将待排序记录序列中的所有记录作为当前待排序区域,从中任选取一个记录(通常可选取第一个记录),以它为关键字作为枢轴,凡是其关键字小于枢轴的记录均移动到该关键字之前,反之移动到该记录之后,这一趟排序后,记录的无序序列R[s..t]将分割成两部分,R[s..i-1]和R[i+1..t],且R[j].key<=R[i].key(s<=j<=i-1,R[i].key为枢轴,i+1<=k<=t)。

 

快速排序的实例:

一趟排序的过程

初始关键字序列:         [51]  33     62     96     87     17     28     51

R[0]=[51]                             i↑(枢轴)                                         ↑j

J向前扫描                         i↑                                                   ↑j

第一次交换之后:         28     33     62     96     87     17     [51]  51

                                               i↑                                                   ↑j

I向后扫描                                            i↑                                ↑j

第二次交换之后:         28     33     [51]  96  87     17     62     51

                                                                 i↑                                ↑j

J向前扫描                                            i↑                       ↑j

第三次交换之后:         28     33     17     96     87     [51]  62  51

I向后扫描                                            i↑                       ↑j

第四次交换之后:         28     33     17     [51]  87     96     62     51

J向前扫描                                                     i↑             ↑j

完成一趟排序:              28     33     17     [51]  87     96     62     51

 

快速排序全过程

 

初始关键字序列:         [51]  33     62     96     87     17     28     51

一趟排序之后:              [28   33     17]   51     [87   96     62     51]

分别进行快速排序:     [17]  28     [33]  51     [51   62]   87     [96]

                                                                                    51     [62]

有序序列:                       17     28     33     51     51     62     87     96

快速排序的Java算法:

 

public class Test2 {

 

    /**

     * @param args

     * 快速排序

     *

     */

   

   

   

   

    public static void main(String[] args) {

       // TODO Auto-generatedmethod stub

      

       //定义一维数组

       int[] R = {132,24,4,436,547,65,87,8,6,9,780,7,325,57,54,46,35,3,42,4};

      

       //掉用quickSort方法,对一维数组排序,初始化low0,最大值

      

       quickSort(R, 0, R.length - 1);

      

      

       //for循环输出排序好的数组

        for(int i = 0; i < R.length; i++) { 

            System.out.print(R[i] + " "); 

        }

      

      

    }

    //快速排序

    //定义quickSort方法

    static void quickSort(int R[], int low, int height) { 

      

       //对记录R[low...height]进行快速排序

        if(low < height) { 

            int result = partition(R, low,height); 

            quickSort(R, low, result -1); 

            quickSort(R, result + 1,height); 

        } 

    } 

  //定义partition方法

    static int partition(int R[], int low, int height) { 

    //交换记录子序列 R[low...height]的记录,使轴记录交换到正确的位置,并返回其所在的位置

        int key = R[low];  //使用key存放枢轴记录的关键字

        while(low < height) { 

        //从表的两端交替向中间扫描

            while(low < height && R[height] >=key) { 

                height--; 

            } 

            R[low] = R[height]; //将比轴小的记录移到低端

            while(low < height && R[low] <= key){ 

                low++; 

            } 

            R[height] = R[low];  //将比轴大的记录移到高端

        } 

        R[low] = key;  //轴记录到位

         

        return low;  //返回轴记录位置

    }

 

}

 

 

快速排序所需的平均时间复杂度为O(n log n)。就平均时间而言,快速排序是目前被认为最好的内部排序方法。但是,若待排记录的初始状态为关键字有序,快速排序将锐化成起泡排序,其时间复杂度为O(n2)。也就是说,一次划分后枢轴两侧的记录数量越接近,排序速度越快,待排序记录越有序,排序速度越慢。为避免排序后记录集中在枢轴一侧的情况,需要在进行快速排序之前,进行”预处理”。这里要说的是随机化快速排序。

随机化快速排序:在待排序序列中随机确定一个记录作为轴值,并把它与第一个记录交换,则一次划分后得到期望均衡的两个子序列,,从而使算法的行为不受待排序序列的不同输入实例的影响,使快速排序在最坏的情况下的时间性能趋近于 平均情况的时间性能。

 

随机化快速排序代码:

import java.util.Random;

 

public class RandomQuickSort {

 

    /**

     * @param args

     * 随机化快速排序

     *

     */

   

   

    private static Random rnd=new Random();

   

   

    public static void main(String[] args) {

       // TODO Auto-generatedmethod stub

      

       //定义一维数组

       int[] R ={132,24,4,436,547,65,87,8,6,9,780,7,325,57,54,46,35,3,42,4};

      

       //掉用quickSort方法,对一维数组排序,初始化low0,最大值

      

       quickSort(R, 0, R.length - 1);

      

      

       //for循环输出排序好的数组

        for(int i = 0; i < R.length; i++) { 

            System.out.print(R[i] + " "); 

        }

      

      

    }

    //快速排序

    //定义quickSort方法

    static void quickSort(int R[], int low, int height) { 

      

       //对记录R[low...height]进行快速排序

        if(low < height) { 

            int result = partition(R, low,height); 

            quickSort(R, low, result -1); 

            quickSort(R, result + 1,height); 

        } 

    } 

  //定义partition方法

    static int partition(int R[], int low, int height) { 

    int point = rnd.nextInt(height-low)+low;

    int temp = R[low];

    R[low]= R[point];

    R[point]= temp;

   

    //交换记录子序列 R[low...height]的记录,使轴记录交换到正确的位置,并返回其所在的位置

        int key = R[low];  //使用key存放枢轴记录的关键字

        while(low < height) { 

        //从表的两端交替向中间扫描

            while(low < height && R[height] >=key) { 

                height--; 

            } 

            R[low] = R[height]; //将比轴小的记录移到低端

            while(low < height && R[low] <= key){ 

                low++; 

            } 

            R[height] = R[low];  //将比轴大的记录移到高端

        } 

        R[low] = key;  //轴记录到位

         

        return low;  //返回轴记录位置

    }

 

}

 

 




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值