快速排序

本文介绍快速排序算法,其思想是分而治之,速度快但不稳定,处理小数据时可能不如简单排序。实现步骤包括选主元,取头、中、尾三个数的中位数最佳;集合划分,利用两个指针交换元素。还给出对数字和对象排序的代码及运行结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

算法概述:

快速排序与归并排序一样,它们的思想都是一种分而治之的思想。快速排序顾名思义它的速度非常快,同时它没有归并排序那么稳定。原因就在于快速排序实现的基础是递归,递归在处理时要开辟很多堆栈以外的内存,所以在处理小数量的数据时,快速排序可能未必有简单排序快。
在这里插入图片描述

实现

第一步:选主元,主元如何选择对快速排序来说十分重要,主元选的不好十分影响他的速度。选主元的方法有很多种,最直接了当的就是以数组中第一个元素为主元。但这样也最复杂,因为我们需要不断遍历后面n-1个元素。所以最好的情况每次选的主元都在这个数组中间 即中分元素。这样可以保证我们分出来的左右两部分都是原来的1/2。选主元的方法。取头,中,尾三个数的中位数。
第二步:集合的划分:集合划分。先将找到的主元放在最右边利用两个指针。一个从头开始遍历(i),一个从主元的前一个元素开始向前遍历(j)。向后遍历的索引遇到比主元大的要停住,向前遍历的遇到比主元小的要停住。两索引同时停住时,交换对应元素,遍历继续。最后当i-j>0时结束。此时交换主元和i索引的对应元素。当数组中有元素与主元相同时选择交换,这样虽然做了许多无用的交换,但保证了主元在中间每次都将序列分成2个长度为n/2的序列。

代码

对数字:

package edu.xalead;

/**
 * 1.选主元
 * 2.根据主元集合划分
 * 3.合并。
 */
public class 快速排序 {

    public static int zhaozhuyaun(int []a,int left,int right){
        int mid=(left+right)/2;
        int temp=0;
        if(a[left]>a[mid]){
            temp=a[left];
            a[left]=a[mid];
            a[mid]=temp;
        }
        if(a[left]>a[right]){
            temp=a[left];
            a[left]=a[right];
            a[right]=temp;
        }
        if(a[mid]>a[right]){
            temp=a[mid];
            a[mid]=a[right];
            a[right]=temp;
        }
        temp=a[mid];
        a[mid]=a[right-1];
        a[right-1]=temp;
        return a[right-1];
    }
    public static void Quitsort(int a[],int left,int right){
        int provit=zhaozhuyaun(a,left,right);
        int i=left;
        int j=right-1;
        int temp=0;
        for (;;){
            while (a[++i]<provit){ }
            while (a[--j]>provit){ };
            if(i<j){
                temp=a[i];
                a[i]=a[j];
                a[j]=temp;
            }else{
                break;
            }
        }
        temp=a[i];
        a[i]=a[right-1];
        a[right-1]=temp;
        if(i==1){
            return;
        }
        Quitsort(a,left,i-1);
        Quitsort(a,i-1,right);
    }
    public static void main(String[] args) {
        int a[]={20,89,96,75,12};
        Quitsort(a,0,a.length-1);
        for(int k=0;k<a.length;k++){
            System.out.print(a[k]+" ");
        }
    }
}

运行结果:
在这里插入图片描述
对对象进行排序:需要实现Comparable接口:Student类

package edu.xalead;

public class Student implements Comparable{
    public Student(String name, int id, char sex) {
        this.name = name;
        this.id = id;
        this.sex = sex;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public char getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", id=" + id +
                ", sex=" + sex +
                '}';
    }

    private String name;
    private int id;
    private char sex;

    @Override
    public int compareTo(Object o) {
        if(o instanceof Student){
            Student s=(Student)o;
            if(this.id>s.id) return 1;
            if(this.id<s.id) return -1;
            return 0;
        }
        throw new RuntimeException("类型不匹配无法比较");
    }
}

排序算法:

package edu.xalead;
import java.util.ArrayList;

public class 快速排序2 {
    public static void swap(ArrayList a,int index1,int index2){
        Student s= (Student) a.get(index1);
        a.set(index1,a.get(index2));
        a.set(index2,s);
    }
    public static Student zhaozhuyaun(ArrayList a, int left, int right){
        int mid =(left+right)/2;
        Comparable o1=(Comparable)a.get(left);
        Comparable o2=(Comparable)a.get(mid);
        if(o1.compareTo(o2)==1){
            swap(a,left,mid);
        }
        Comparable o3=(Comparable)a.get(left);
        Comparable o4=(Comparable)a.get(right);
        if(o3.compareTo(o4)==1){
            swap(a,left,right);
        }
        Comparable o5=(Comparable)a.get(mid);
        Comparable o6=(Comparable)a.get(right);
        if(o5.compareTo(o6)==1){
            swap(a,mid,right);
        }
        swap(a,mid,right-1);
        Student aa= (Student) a.get(right-1);
        return aa;
    }
    public static void QuickSort(ArrayList a,int left,int right){
        Student provit=zhaozhuyaun(a,left,right);
        int i=left;
        int j=right-1;
        for (;;) {
            while (((Comparable)a.get(++i)).compareTo(provit) == -1) {}
            while (((Comparable)a.get(--j)).compareTo(provit) == 1) {}
            if (i < j) {
                swap(a, i, j);
            } else {
                break;
            }
        }
        swap(a,i,right-1);
        if(i==1) return;
        QuickSort(a,left,i-1);
        QuickSort(a,i-1,right);
    }

    public static void main(String[] args) {
        ArrayList a=new ArrayList();
        a.add(new Student("zhangsan",105,'M'));
        a.add(new Student("lisi",102,'F'));
        a.add(new Student("wangmazi",103,'M'));
        QuickSort(a,0,a.size()-1);
        System.out.println(a);
    }
}

运行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值