基本排序方式——(三)快速排序

一.快速排序

1.思想

(1)选取一个数为基准数(一般是数组的第一个元素)
(2)分区:将数组中比基准数大的放到它的后面,小的放在前面,(可以设置两个游标i,j,i,j分别是数组中首尾元素的下标,程序执行一次,i++,j - -)
(3)分好后,然后将这个基准数的左右两个分区再继续执行第二步,直到区内只剩一个元素,可以用递归来解决。

  • 举例说明:
a[] ={56, 23, 67, 26, 85, 14, 17, 68, 73, 45, 77}
第一步:
    当前基准数=56  i=0,j=10。
    (1){45,23,67,26,85,14,17,68,73,56,77}
         {45,23,56,26,85,14,17,68,73,67,77}
    (2){45,23,17,26,85,14,56,68,73,67,77}
         {45,23,17,26,56,14,85,68,73,67,77}
    (3){45,23,17,26,14,56,85,68,73,67,77}
第二步:经过上一步后,需要对{45,23,17,26,14}和{85,68,73,67,77}进行第一步的处理,直到分区中只有一个元素时
    当前基数=45,i=0;j=i-1(这个i时第一步程序运行完成得到的i)
    (1)14,23,26,45
2.算法设计分析(完全个人理解)
设计思路

(1)j变化:先从后往前遍历,直到找到比基准数小的数,将此数赋给a[i](这是开始基准数所在的位置)。然后i变化:从前往后遍历,找到比基准数大的数,将其赋给a[j](前面程序结束时基准数的位置),同时i随着移动。然后重复前面步骤,直到i=j。
(2)一开始找到符合条件的数时,如(1)中所说,我采用的时将基准数与找到的数进行互换,后来发现,不需要这样麻烦,因为看整个过程(不要把i和j分开),可以再每次循环前经基准数提取出来,这样就只需赋值就行了,我觉得每一轮排序就是基准数的归位过程。

关键(自认为)
  • 程序一轮排序结束,也就是一个基准数的位置确定,那么接下来就是把原来的数组分成两部分,每部分执行(1)步骤,如何确定左边部分的j的值和右边部分i的值?
  • 所以每一轮排序必须要返回每次基准数归为后的i的值,这样下一个基准数归位时左右两边的j和i的值才能确定。
3.代码
package org.wetmo.demo1;
public class Denokuaipai {
    public static void main(String[] args) {
        int[] arr = {56, 23, 67, 26, 85, 14, 17, 68, 73, 45, 77};
        int i = 0, j = arr.length - 1;
        show1(arr, i, j);
        for (int i1 = 0; i1 < arr.length; i1++) {
            System.out.print(arr[i1]+" ");
        }
    }
    public static  int show(int[] a, int i, int j) {
        int tmp = a[i]; //将基准数提取出来
        while (i < j) {
            while (i < j && tmp <= a[j]) {
                j--;//比较一次,j往前移动一次
            }
            a[i] = a[j];
            while (i < j && tmp >=a[i]) {
                i++;//比较一次,i往后移动一下
            }
            a[j] = a[i];
        }
        a[i]=tmp;//程序的最后一步,基准数归位
        return i;返回这一轮循环结束后基准数成功归位后的元素下标,为下次对
    }
    public static void show1(int[] a,int s,int t){
        if (s<t) {
            int i = show(a, s, t);
            show1(a, s, i - 1);
            show1(a, i + 1, t);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值