数据结构:交换排序中的快速排序

快速排序:

public class QuickSort {

    public static void main(String[] args) {
        int[] a=new int[]{49,38,65,97,76,13,27,49};
        int n=a.length;

        Quicksort0(a,0,n-1);

        for (int c=0;c<n;c++){
            System.out.print(a[c]+" ");
        }
        System.out.println();
    }
    static void Quicksort0(int[] a,int low,int high){
        if (low<high){//递归跳出条件
            //Partition()就是划分操作,将表a[low.....high]划分为满足上述条件的两个子表
            int pivotpos=Partition(a,low,high);  //划分
            Quicksort0(a,low,pivotpos-1);   //依次对两个子表进行递归排序,这是比枢轴元素小的一边
            Quicksort0(a,pivotpos+1,high);  //这是比枢轴元素大的一边
        }

    }

    //一趟划分
    static int Partition(int[] a, int low, int high) {
        int pivot=a[low];   //枢轴
        while(low<high){
            while (low<high&&a[high]>=pivot) --high;
            a[low]=a[high]; //将比枢轴小的元素移动到左端
            while (low<high&&a[low]<=pivot)  ++low;
            a[high]=a[low]; //将比枢轴大的元素移动到右端
        }
        a[low]=pivot;
        return low;
    }
}

时间复杂度:O(n^2)

快速排序是所有内部排序算法中平均性能最优的排序算法。 

先熟悉排序流程、逻辑和概念

快速排序算法通过多次比较和交换来实现排序,其排序流程如下:

(1)首先设定一个分界值,通过该分界值将数组分成左右两部分。

(2)将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于分界值,而右边部分中各元素都大于或等于分界值。

(3)然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。

(4)重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好

简单来说:

最开始学习编程,遇到排序问题,一般都是用冒泡法,因为冒泡法好理解,代码量少。但是这种算法时间复杂度高,当需要排序的元素较多时,程序运行时间很长,因此产生了快速排序算法。该算法的实现可分为以下几步:

1. 在数组中选一个基准数(通常为数组第一个);

2. 将数组中小于基准数的数据移到基准数左边,大于基准数的移到右边;

3. 对于基准数左、右两边的数组,不断重复以上两个过程,直到每个子集只有一个元素,即为全部有序。

右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。

 快速排序动画演示

可能描述得有些抽象,接下来用图一步一步的示意:

将数组第一个数23赋给temp变量,指针 i 指向数组第一个元素,指针 j 指向数组最后一个元素

从 j 开始遍历(从右往左),遇到13时,因为13<=temp,因此将arr[j]填入arr[i]中,即此时指针 i 指向的数为13;

再从 i 遍历(从左往右),遇到45时,因为45>temp,因此将arr[i]填入arr[j]中,此时指针 j 指向的数为45;

继续从 j 遍历,遇到11时,因为11<=temp,因此将arr[j]填入arr[i]中,即此时指针 i 指向的数为11;

从 i 遍历,遇到89时,因为89>temp,因此将arr[i]填入arr[j]中,此时指针 j 指向的数为89;

从 j 遍历,遇到17时,因为17<=temp,因此将arr[j]填入arr[i]中,即此时指针 i 指向的数为17;

从 i 遍历,遇到72时,因为72>temp,因此将arr[i]填入arr[j]中,此时指针 j 指向的数为72;

从 j 遍历,遇到3时,因为3<=temp,因此将arr[j]填入arr[i]中,即此时指针 i 指向的数为3;

从 i 遍历,遇到26时,因为26>temp,因此将arr[i]填入arr[j]中,此时指针 j 指向的数为26;

从 j 遍历,和 i 重合;

将 temp(基准数23)填入arr[i]中。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值