Java-快速排序

排序算法(Sorting algorithm)是计算机科学最古老、最基本的课题之一。要想成为合格的程序员,就必须理解和掌握各种排序算法。

目前,最常见的排序算法大概有七八种,其中"快速排序"(Quicksort)使用得最广泛,速度也较快。它是图灵奖得主C. A. R. Hoare(1934--)于1960时提出来的。

"快速排序"的思想很简单,整个排序过程只需要三步:

  (1)在数据集之中,选择一个元素作为"基准"(pivot)。

  (2)所有小于"基准"的元素,都移到"基准"的左边;所有大于"基准"的元素,都移到"基准"的右边。

  (3)对"基准"左边和右边的两个子集,不断重复第一步和第二步,直到所有子集只剩下一个元素为止。

举例来说,现在有一个数据集{85, 24, 63, 45, 17, 31, 96, 50},怎么对其排序呢?

第一步,选择中间的元素45作为"基准"。(基准值可以任意选择,但是选择中间的值比较容易理解。

第二步,按照顺序,将每个元素与"基准"进行比较,形成两个子集,一个"小于45",另一个"大于等于45"。

第三步,对两个子集不断重复第一步和第二步,直到所有子集只剩下一个元素为止。

下面我们通过另外一个案例来演示一下快速排序的基本步骤: 以序列 46 30 82 90 56 17 95 15   共8个元素

    初始状态:     46  30  82  90  56  17  95  15        选择46 作为基准值,i = 0, j = 7

           i = 0                                j = 7

                   15  30  82  90  56  17  95  46       15 < 46, 交换 15 和 46,移动 i, i = 1

             i = 1                           j = 7

            15  30  82  90  56  17  95  46       30 < 46, 不需要交换,移动 i , i = 2

               i = 2                   j = 7

            15  30  46  90  56  17  95  82       82 > 46, 交换82 和 46,移动 j , j = 6

               i = 2               j = 6

            15  30  46  90  56  17  95  82       95 > 46, 不需要交换,移动 j , j = 5

               i = 2         j = 5

            15  30  17  90  56  46  95  82       17 < 46, 交换46 和 17,移动 i, i = 3

                 i = 3    j = 5

            15  30  17  46  56  90  95  82       90 > 46, 交换90 和 46,移动 j , j = 4

               3 = i    j = 4

            15  30  17  46  56  90  95  82       56 > 46, 不需要交换,移动 j , j = 3

                     i  =  j = 3

    

    i = j = 3, 这样序列就这样分割成了两部分,左边部分{15, 30, 17} 均小于 基准值(46);右边部分 {56, 90,95,82},均大于基准值。这样子我们就达到了分割序列的目标。在接着对子序列用同样的办法进行分割,直至子序列不超过一个元素,那么排序结束,整个序列处于有序状态。

快速排序动画演示

 

 

对整个算法总结:

1.i =L; j = R; 将基准数挖出形成第一个坑a[i]。

2.j--由后向前找比它小的数,找到后挖出此数填前一个坑a[i]中。

3.i++由前向后找比它大的数,找到后也挖出此数填到前一个坑a[j]中。

4.再重复执行2,3二步,直到i==j,将基准数填入a[i]中。

5.对两个子集分治排序,直至子序列不超过一个元素,那么排序结束,整个序列处于有序状态。

CODE:

package 排序;

/**
 * @version v1.0
 * @Package 排序
 * @auther LaurenceLau
 * @date 2020/4/21,23:33
 * @description
 */
import org.junit.Test;
public class QuickSort {
        public static int adjustArray(int s[], int l, int r) {//返回调整后基准数的位置
            int i = l, j = r;
            int x = s[l];//是s[i]即是s[l]就是第一个坑
            while (i < j) {
                //从右向左找小于X的数来填s[i]
                while (i < j && s[j] >= x)
                    j--;
                if (i < j) {
                    s[i] = s[j];//将s[j]填到s[i]中,s[j]就形成了一个新的坑
                    i++;
                }
                //从左向右找大于或等于x的数来填s[j]
                while (i < j && s[i] < x)
                    i++;
                if (i < j) {
                    s[j] = s[i];
                    j--;
                }
            }
            //退出时,等于j,将x填到这个坑中。
            s[i] = x;
            return i;
        }

        //对两个子集采用分治法
        public static void quick_sort(int s[], int l, int r) {
            if (l < r) {
                int i = adjustArray(s, l, r);//先用挖坑填数法调整s[]
                quick_sort(s, l, i - 1);//递归调用
                quick_sort(s, i + 1, r);
            }
        }

        public static void p(int a[],int n){
            for(int i=0;i<n;i++)
                System.out.print(a[i]+"  ");

        }


        @Test
        public static void main(String[] args) {
            int a[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
            p(a, 10);
            quick_sort(a, 0, 9);//注意最后一个参数是n-1;
            System.out.println(" ");
            p(a, 10);
        }


}

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值