算法之快速排序

快速排序与之前的排序完全不同,快速排序的思想也有些复杂,它使用了分治的思想,什么叫分治思想呢?
分治思想便是把一个大的问题划分成两个中等的问题,然后两个中等的问题继续划分成4个小问题,解决了这个4个小问题便解决了这个大问题了。
而快速排序便是将一个序列中出一个分界数,然后把一个序列划分成两个序列,而这两个序列划分的标准就是其中一个序列的数比分界的数字小或者相等,另一个序列的数比分界数大;然后分别有将这两个序列分成4个序列,最后将整个序列排好序。
实现快速排序最重要的就是找出分界数和怎么划分序列,找分界数比较简单,因为谁也不知道这些数字最后的排列,所以我们便以序列的第一个数字为分界数,每次划分的序列一个都是比第一个数字大的,一个是小于等于的。那剩下的就是如何划分了。
关于划分,快速排序里用到了指针,总共有2个指针,一个指向序列的第一位,一个指向序列的最后一位。我们就按照从小到大的顺序排列,这样我们以3,5,2,6,4,1为例,首先分界数便是第一个数字,也就是3,然后有两个指针,分别指向第一位和最后一位,也就是5和1,然后我们就要划分成两个序列了,一个的是比3小的,一个是比3大的,首先是右边的指针也就是指向数字1的指针,它与3相比,显然比3小,因为我们是按照从小到大排列的,所以它应该在3的左边,这个时候我们将这个值赋给左边的指针对应的位置,这个时候序列变为1,5,2,6,4,1,这个时候,左边的指针开始行动了,它也是与3对比,因为不大于3所以继续往后移,但是5比3大,这个时候就将5赋给右边的的指针指的位置,序列变成了1,5,2,6,4,5;此时左边的指针指向序列的第二位,此时右边的指针继续对比,找到比分界数字小的数字然后赋值给左边指针所指向的位置,若是找到两个指针重合了,此时便把分界数赋值给指针所指向的位置,这样便完成了分界数左边的数比分界数小,右边的数比分界数大了。此时第一次便结束了,需要返回一个当前指针的位置,因为你还要继续将两个序列分成4个序列,这个位置与另外两个序列指针所指向的位置有关。
关键代码如下:

public static int getMidel(int[] list,int low,int high){
        int temp = list[low];
        while(high > low){
            while (high > low && list[high] >= temp){
                high--;
            }
            list[low] = list[high];
            while(high > low && list[low] <= temp){
                low++;
            }
            list[high] = list[low];
        }
        list[low] = temp;
        return low;
    }

刚刚只是完成了第一步,后面还需要不断的继续这样的操作,所以使用一个递归操作,代码如下:

public static void quick(int[] list,int low,int high){
        if(high > low){
            int mo = getMidel(list,low,high);
            quick(list,low,mo-1);
            quick(list,mo+1,high);
        }
    }

完整代码如下:

package com.itds.test;

/**
 * @author tb
 * @ClassName KuaiSu
 * @description 快速排序
 * @DATE 2019/4/10 0010 10:44
 **/
public class KuaiSu {
    public static int getMidel(int[] list,int low,int high){
        int temp = list[low];
        while(high > low){
            while (high > low && list[high] >= temp){
                high--;
            }
            list[low] = list[high];
            while(high > low && list[low] <= temp){
                low++;
            }
            list[high] = list[low];
        }
        list[low] = temp;
        return low;
    }

    public static void quick(int[] list,int low,int high){
        if(high > low){
            int mo = getMidel(list,low,high);
            quick(list,low,mo-1);
            quick(list,mo+1,high);
        }
    }
    public static void main(String[] args) {
        int a[] = {3,5,2,6,4,1};
        System.out.println("排序前的数组为:");
        for(int t:a){
            System.out.print(t+" ");
        }
        System.out.println(" ");
        quick(a,0,a.length-1);
        System.out.println("排序后的数组为:");
        for(int t:a){
            System.out.print(t+" ");
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值