zoukankan      html  css  js  c++  java
  • 快速排序Quick_Sort

    快排——排序中的明星算法,也几乎是必须掌握的算法,这次我们来领略以下快排为何魅力如此之大。

    快排主要有两种思路,分别是挖坑法和交换法,这里我们以挖坑法为例来进行介绍,交换法可以参考这篇博文。值得一提的是,这篇博文下面有许多批评的声音,质疑为何需要交换,其实是不了解快排具有两种形式,而作者采用了较为不常用的交换法,并无不妥。

    挖坑法是指从数组中设定一个支点,将小于该支点的数据移到左边,而大于该支点的数据被移到右边,之后分别对支点左边和右边形成的子数组继续进行快排,采用分治法的思想。以下面的数组为例:

     首先选取一个支点,一般都随机选,我们以第一个元素为例。然后设置两个哨兵位置i和j。其中i设置为0,j设置为7【一个是数组的最前面,一个是数组的最后面。】从j开始,如果j位置上的元素大于支点,那么它已经符合我们的要求,即大于支点的元素放置在支点的右边,就无需进行移动,j直接减小一位,继续进行判断。如果小于支点元素,将j位置元素放置在i的位置上。那么7>6,所以j接着会被移至6,2<6,所以将i位置上的元素设置为2。

     然后换到i的方向,与j对称,如果i位置上的元素小于支点,i增加一位,反之将i位置上的元素放到j的位置上。2<6,因此i增至1。4仍然小于6,直到8>6。所以将8放置在j的位置上。

     再次交换方向,发现1<6,数组变成:

     同样的,有9>6和3<6,所以9会被放在位置5,而3被放在位置3。

    当i和j已经相等时,将支点放在中心的位置,即

     此时,支点左边都是小于6的元素,右边都是大于6的元素。然后对于左边的子数组{2,4,1,3}和右边的子数组{9,8,7}进行同样的操作。根据递归继序进行排序。

    时间复杂度:快排几乎是最快的排序算法之一,时间复杂度为O(nlogn)

    代码:

        static void quick(int []a, int i, int j)
        {
            int k = i;
            int m = i;
            int l = j;
            int pivot = a[i];
    
            while (j > i)
            {
                while (a[j] > pivot && j != i) {
                    j--;
                }
                if (i != j)
                    a[i] = a[j];
                else {
                    a[j] = pivot;
                    k = j;
                    break;
                }
                while(a[i] < pivot && j != i)
                    i++;
    
                if (i != j)
                    a[j] = a[i];
                else {
                    a[i] = pivot;
                    k = i;
                }
    
            }

        for (int m:a)
          System.out.print(m+" ");
        System.out,println();
    if(k >m && k < l) { quick(a, m, k - 1); quick(a, k + 1, l); } } public static void main(String []args) { int [] a = {6,4,8,9,3,1,2,7}; quick(a,0,a.length - 1); }

    结果:

    2 4 1 3 6 9 8 7  //第一趟排序后,小于6的元素都在左边,大于6的元素都在右边
    1 2 4 3 6 9 8 7  //对{2,4,1,3}快排之后,以2为支点
    1 2 4 3 6 9 8 7  //对{1}进行快排,i==j直接结束
    1 2 3 4 6 9 8 7  //对{4,3}进行排序,直接交换
    1 2 3 4 6 7 8 9  //对{9,8,7}进行快排
  • 相关阅读:
    Javascript的ajax
    关于跨模块拿取数据的思路AJAX实现
    JAVA的整型与字符串相互转换
    接口返回数据和数组
    接口返回数据是一条数据和一个数组的区别
    最初的代码
    http发送请求方式;分为post和get两种方式
    Java学习---- 数组的引用传递
    Java学习--数组与方法
    Java学习--数组的定义和使用
  • 原文地址:https://www.cnblogs.com/lbrs/p/11902116.html
Copyright © 2011-2022 走看看